zoukankan      html  css  js  c++  java
  • Linux 信号量之Posix基于内存的信号量

    信号量(semaphore),也和互斥锁一样提供了线程间或者进程间的同步功能。

    信号量有三种:

    信号量比互斥锁高级,互斥锁只允许一个线程访问临界区,信号量可以多个,可以把信号量看作成互斥锁的升级版,但是如果能用互斥锁解决,就用互斥锁,互斥锁比信号量节省资源。

    这篇文章只介绍Posix基于内存的信号量

    1,单个生产者和单个消费者

    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <fcntl.h>       
    #include <sys/stat.h>    
    #include <semaphore.h>
    
    #define NBUFF 10
    
    int nitems;
    struct {
      int buff[NBUFF];
      sem_t mutex, nempty, nstored;
    } shared;
    
    void* produce(void *args);
    void* consume(void* args);
    
    int main(int argc, char** argv){
    
      pthread_t tid_produce, tid_consume;
    
      if(argc != 2){
        printf("usage error
    ");
        exit(1);
      }
    
      nitems = atoi(argv[1]);
    
      //create 3 semaphore
      sem_init(&shared.mutex, 0, 1);
      sem_init(&shared.nempty, 0, NBUFF);
      sem_init(&shared.nstored, 0, 0);
    
      pthread_create(&tid_produce, NULL, produce, NULL);
      pthread_create(&tid_consume, NULL, consume, NULL);
    
      pthread_join(tid_produce, NULL);
      pthread_join(tid_consume, NULL);
    
      sem_destroy(&shared.mutex);
      sem_destroy(&shared.nempty);
      sem_destroy(&shared.nstored);
      exit(0);
    }
    
    void* produce(void *args){
      int i;
      for(i = 0; i < nitems; ++i){
        sem_wait(&shared.nempty);
        sem_wait(&shared.mutex);
        shared.buff[i % NBUFF] = i;
        sem_post(&shared.mutex);
        sem_post(&shared.nstored);
      }
    
      return NULL;
    }
    
    void* consume(void* args){
      int i;
      for(i = 0; i < nitems; ++i){
        sem_wait(&shared.nstored);
        sem_wait(&shared.mutex);
        shared.buff[i % NBUFF] = i;
        sem_post(&shared.mutex);
        sem_post(&shared.nempty);
      }
    
      return NULL;
    }
    
    
    

    2,多个生产者和单个消费者

    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <fcntl.h>       
    #include <sys/stat.h>    
    #include <semaphore.h>
    
    #define NBUFF 10
    #define MAXTHRS 100
    #define min(x,y) ( x > y ? y:x )
    
    int nitems, nproducers;
    
    struct {
      int buff[NBUFF];
      int idx;
      int val;
      sem_t mutex, nempty, nstored;
    } shared;
    
    void* produce(void *args);
    void* consume(void* args);
    
    int main(int argc, char** argv){
    
      int i, count[MAXTHRS];
      pthread_t tid_produce[MAXTHRS], tid_consume;
    
      if(argc != 3){
        printf("usage error
    ");
        exit(1);
      }
    
      nitems = atoi(argv[1]);
      nproducers = min(atoi(argv[2]), MAXTHRS);
    
      //create 3 semaphore
      sem_init(&shared.mutex, 0, 1);
      sem_init(&shared.nempty, 0, NBUFF);
      sem_init(&shared.nstored, 0, 0);
    
      for(i = 0; i < nproducers; ++i){
        count[i] = 0;
        pthread_create(&tid_produce[i], NULL, produce, &count[i]);
      }
      pthread_create(&tid_consume, NULL, consume, NULL);
    
      for(i = 0; i < nproducers; ++i){
        pthread_join(tid_produce[i], NULL);
        printf("count[%d] = %d
    ", i, count[i]);
      }
      pthread_join(tid_consume, NULL);
    
      sem_destroy(&shared.mutex);
      sem_destroy(&shared.nempty);
      sem_destroy(&shared.nstored);
      exit(0);
    }
    
    void* produce(void *arg){
      int i;
      for(i = 0; i < nitems; ++i){
        sem_wait(&shared.nempty);
        sem_wait(&shared.mutex);
    
        if(shared.idx >= nitems){
          sem_post(&shared.nempty);//注意点
          sem_post(&shared.mutex);
          return NULL;// all done
        }
        
        shared.buff[shared.idx % NBUFF] = shared.val;
        shared.idx++;
        shared.val++;
        sem_post(&shared.mutex);
        sem_post(&shared.nstored);
        *((int*) arg) += 1;
      }
    
      return NULL;
    }
    
    void* consume(void* args){
      int i;
      for(i = 0; i < nitems; ++i){
        sem_wait(&shared.nstored);
        sem_wait(&shared.mutex);
        if(shared.buff[i % NBUFF] != i){
          printf("error:buff[%d] = %d
    ", i, shared.buff[i % NBUFF]);
        }
        sem_post(&shared.mutex);
        sem_post(&shared.nempty);
      }
    
      return NULL;
    }
    
    

    3,多个生产者和多个消费者

    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <fcntl.h>       
    #include <sys/stat.h>    
    #include <semaphore.h>
    
    #define NBUFF 10
    #define MAXTHRS 100
    #define min(x,y) ( x > y ? y:x )
    
    int nitems, nproducers, nconsumers;
    
    struct {
      int buff[NBUFF];
      int idx;
      int val;
      int gidx;
      int gval;
      sem_t mutex, nempty, nstored;
    } shared;
    
    void* produce(void *args);
    void* consume(void* args);
    
    int main(int argc, char** argv){
    
      int i, prodcount[MAXTHRS], conscount[MAXTHRS];
      pthread_t tid_produce[MAXTHRS], tid_consume[MAXTHRS];
    
      if(argc != 4){
        printf("usage error
    ");
        exit(1);
      }
    
      nitems = atoi(argv[1]);
      nproducers = min(atoi(argv[2]), MAXTHRS);
      nconsumers = min(atoi(argv[3]), MAXTHRS);
    
      //create 3 semaphore
      sem_init(&shared.mutex, 0, 1);
      sem_init(&shared.nempty, 0, NBUFF);
      sem_init(&shared.nstored, 0, 0);
    
      for(i = 0; i < nproducers; ++i){
        prodcount[i] = 0;
        pthread_create(&tid_produce[i], NULL, produce, &prodcount[i]);
      }
      for(i = 0; i < nconsumers; ++i){
        conscount[i] = 0;
        pthread_create(&tid_consume[i], NULL, consume, &conscount[i]);
      }
    
      for(i = 0; i < nproducers; ++i){
        pthread_join(tid_produce[i], NULL);
        printf("prodcount[%d] = %d
    ", i, prodcount[i]);
      }
      for(i = 0; i < nconsumers; ++i){
        pthread_join(tid_consume[i], NULL);
        printf("conscount[%d] = %d
    ", i, conscount[i]);
      }
    
      sem_destroy(&shared.mutex);
      sem_destroy(&shared.nempty);
      sem_destroy(&shared.nstored);
      exit(0);
    }
    
    void* produce(void *arg){
      int i;
      for(i = 0; i < nitems; ++i){
        sem_wait(&shared.nempty);
        sem_wait(&shared.mutex);
    
        if(shared.idx >= nitems){
          sem_post(&shared.nstored);//注意点
          sem_post(&shared.nempty);//注意点
          sem_post(&shared.mutex);
          return NULL;// all done
        }
        
        shared.buff[shared.idx % NBUFF] = shared.val;
        shared.idx++;
        shared.val++;
        sem_post(&shared.mutex);
        sem_post(&shared.nstored);
        *((int*) arg) += 1;
      }
    
      return NULL;
    }
    
    void* consume(void* arg){
      int i;
      for(; ;){
        sem_wait(&shared.nstored);
        sem_wait(&shared.mutex);
        
        if(shared.gidx >= nitems){
          sem_post(&shared.nstored);//注意点
          sem_post(&shared.mutex);
          return NULL;// all done
        }
        i = shared.gidx % NBUFF;
        if(shared.buff[i] != shared.gval){
          printf("error:buff[%d] = %d
    ", i, shared.buff[i]);
        }
        shared.gidx++;
        shared.gval++;
        
        sem_post(&shared.mutex);
        sem_post(&shared.nempty);
        *((int*) arg) += 1;
      }
    
      return NULL;
    }
    
    

    c/c++ 学习互助QQ群:877684253

    本人微信:xiaoshitou5854

  • 相关阅读:
    Excel 如何在程序运行期间提示信息“正在运行中。。。请稍候 38云淡淡
    EXT学习笔记第一课
    java学习日志1
    C语言基础知识
    js所学知识点
    javascript 取最大值和最小值!
    html常用标签
    javascript4位随机数(字体都有颜色)
    marginpadding区别及bug
    数独的优化回朔算法(四)
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/11070030.html
Copyright © 2011-2022 走看看