linux多线程编程详解教程(线程通过信号量实现通信代码)

2019-09-23 09:44:03刘景俊

while(b->writepos == b->readpos) 

printf("wait for not emptyn"); 
pthread_cond_wait(&b->notempty,&b->lock); 
}
data=b->buffer[b->readpos]; 
b->readpos++;
b->readpos %= BUFFER_SIZE;
pthread_cond_signal(&b->notfull);  //signal buffer is not full
pthread_mutex_unlock(&b->lock); 
return data;
}

#define OVER -1

struct prodcons buffer; 

void * producer(void * data) 

int n; 
for(n=0; n<50; ++n) 
{
printf("put-->%dn",n); 
put(&buffer,n); 

put(&buffer,OVER); 
printf("producer stoppedn"); 
return NULL; 

void * consumer(void * data) 

int n; 
while(1) 

int d = get(&buffer); 
if(d == OVER) break; 
printf("get-->%dn",d); 
}
printf("consumer stoppedn"); 
return NULL; 

int main() 

pthread_t tha,thb; 
void * retval; 

init(&buffer); 
pthread_creare(&tha,NULL,producer,0); 
pthread_creare(&thb,NULL,consumer,0); 

pthread_join(tha,&retval); 
pthread_join(thb,&retval); 

return 0; 
}

3)信号量
如同进程一样,线程也可以通过信号量来实现通信,虽然是轻量级的。

信号量函数的名字都以"sem_"打头。线程使用的基本信号量函数有四个。

#include <semaphore.h>
int sem_init(sem_t *sem , int pshared, unsigned int value);

这是对由sem指定的信号量进行初始化,设置好它的共享选项(linux只支持为0,即表示它是当前进程的局部信号量),然后给它一个初始值VALUE。

两个原子操作函数:这两个函数都要用一个由sem_init调用初始化的信号量对象的指针做参数。


int sem_wait(sem_t *sem); //给信号量减1,对一个值为0的信号量调用sem_wait,这个函数将会等待直到有其它线程使它不再是0为止。
int sem_post(sem_t *sem); //给信号量的值加1

int sem_destroy(sem_t *sem);

这个函数的作用是再我们用完信号量后都它进行清理。归还自己占有的一切资源。

用信号量实现生产者消费者:

这里使用4个信号量,其中两个信号量occupied和empty分别用于解决生产者和消费者线程之间的同步问题,pmut用于多个生产者之间互斥问题,cmut是用于多个消费者之间互斥问题。其中empty初始化为N(有界缓区的空间元数),occupied初始化为0,pmut和cmut初始化为1。

参考代码:


#define BSIZE 64

typedef struct
{
char buf[BSIZE];
sem_t occupied;
sem_t empty;
int nextin;
int nextout;
sem_t pmut;
sem_t cmut;
}buffer_t;

buffer_t buffer;

void init(buffer_t * b)