Linux下生产者消费者模型——信号量实现

1、信号量是用来解决线程间同步或互斥的一种机制,也是一个特殊的变量,变量的值代表着当前可以利用的资源数。如果等于0就代表着当前没有资源可用。

2、信号量只能进行两个原子操作P操作和V操作

P操作:如果有可用的资源(信号量>0),那么占用一个资源(信号量-1)。如果没有可用的资源(信号量=0),则进程被阻塞,直到系统重新给他分配资源。

V操作:如果在该信号量的等待队列中进程在等待该资源,则唤醒一个进程,否则释放一个资源(信号量+1)

3、信号量分类:二值信号量、计数信号量

4、注意:POSIX提供两种信号量:有名信号量和无名信号量,有名信号量一般是用在进程间同步,无名信号量一般是用在线程间同步(但也可以用在相关进程间)

两中信号量的操作流程,大概有下面几点不同。

Linux下生产者消费者模型——信号量实现_第1张图片

 基于我们的生产者消费者代码,我们简单说一下sem_init函数:

int sem_init(sem_t* sem,int pshared,unsigned int value);

        sem是要进行初始化的信号量;

        pshared==0用于同一进程下多个线程的同步;

        pshared>0 用于多个相关进程间的同步(即fork产生的);

        value则是信号量的初始值;

生产者消费者——基于信号量实现:

简单说明:一个生产者线程,一个消费者线程,生产者线程产生1-100的随机数,保存到环形数组里面。消费者线程取出环形数组数据打印到屏幕上。环形数组长度N,用来表示共享内存区域的相同资源。需要用到两个信号量:space:用来表示数组中空元素资源的个数。full:表示数组中有数据元素资源的个数。

代码:

    1 #include                                                                                                                                                                                    
    2 #include 
    3 #include 
    4 #include 
    5 #include 
    6 #include 
    7 #include 
    8 #include 
    9 //一个生产者线程,一个消费者线程。共享内存为环形数组,两个信号两,一个记录数组有几个数 
      据,一个记录有几个空位。
   10 #define N 10
   11 sem_t space;//记录数组中空元素个数
   12 sem_t full;//记录数组中有数据元素个数
   13 int arry[N];//数组来表示内存中相同的有限的资源
   14 //生产者
   15 void * producer(void * arg)
   16 {
   17     int i=0;
   18     while(1)
   19     {
   20         sem_wait(&space);//对space做P操作,空位-1。
   21         arry[i]=rand()%100+1;
   22         printf("+++++++++生产者生产了数据=%d\n",arry[i]);
   23         sem_post(&full);//对full执行V操作,表示有数据元素个数+1。
   24         i=(i+1)%N;
   25         usleep((rand()%5+1)*50000);
   26     }
   27     return NULL;
   28 }
   29 //消费者
   30 void* cosumer(void* arg)
   31 {
   32     int i=0;
   33     while(1)
   34     {
   35         sem_wait(&full);//对full做P操作,表示有数据元素个数-1
   36         printf("---------消费者处理了数据=%d\n",arry[i]);//这里处理数据只是打印出来。
   37         sem_post(&space);//对space做V操作,表示空元素个数+1
   38         i=(i+1)%N;
   39         usleep((rand()%5+1)*50000);
   40     }
   41     return NULL;
   42 }
   43 //主线程什么都不做,只是定义
   44 int main(int argc, char* argv[])
   45 {
   46     srand(time(NULL));
   47     sem_init(&space,0,N);
   48     sem_init(&full,0,0);//初始化信号量
   49     //定义生产者消费者线程,且创建线程。
   50     pthread_t p_tid;
   51     pthread_t c_tid;
   52     pthread_create(&p_tid,NULL,producer,NULL);
   53     pthread_create(&c_tid,NULL,cosumer,NULL);
   54 
   55     while(1);//线程三依托进程的,我们不让进程结束
   56     sem_destroy(&space);
   57     sem_destroy(&full);
   58     pthread_exit(NULL);
   59 }
   60               

执行结果:

Linux下生产者消费者模型——信号量实现_第2张图片

 

你可能感兴趣的:(Linux,生产者消费者模型,信号,开发语言,linux,c++,编辑器)