1. #include<pthread.h> 
  2. #include<semaphore.h> 
  3. #include<stdlib.h> 
  4. #include<stdio.h> 
  5. #include<string.h> 
  6. #include<unistd.h> 
  7.  
  8. #define SIZE 3 
  9. #define STR_SIZE 20 
  10.  
  11. pthread_mutex_t mutex; //全局变量对main 及 线程函数都可见
  12. sem_t read_sem, write_sem; //全局变量对main 及 线程函数都可见
  13.  
  14. struct _buf_ 
  15.     char* buf[SIZE]; 
  16.     int front, rear; 
  17. }buffer; //循环队列结构体
  18.  
  19. void thread(void) 
  20.     while(1) 
  21.     { 
  22.         if(0 != sem_wait(&read_sem)) 
  23.         { 
  24.             perror("sem_wait_0"); 
  25.             exit(1); 
  26.         } 
  27.      
  28.         if(0 != pthread_mutex_lock(&mutex)) 
  29.         { 
  30.             perror("pthread_mutex_lock_0"); 
  31.             exit(1); 
  32.         } 
  33.      
  34.         fputs("output characters:\n",stdout); 
  35.      
  36.         fputs(buffer.buf[buffer.front],stdout); 
  37.      
  38.         buffer.front = (buffer.front + 1) % SIZE; 
  39.      
  40.         if(0 != pthread_mutex_unlock(&mutex)) 
  41.         { 
  42.             perror("pthread_mutex_lock_0"); 
  43.             exit(1); 
  44.         } 
  45.         if(0 != sem_post(&write_sem)) 
  46.         { 
  47.             perror("sem_wait_0"); 
  48.             exit(1); 
  49.         } 
  50.      
  51.         sleep(10); 
  52.     } 
  53.      
  54.  
  55. int main(void) 
  56.     //初始化循环队列结构体 
  57.     int i; 
  58.     bufferbuffer.front = buffer.rear = 0
  59.     for(i=0; i < SIZE; i++) 
  60.     { 
  61.         buffer.buf[i] =(char*) malloc(STR_SIZE); 
  62.     } 
  63.     //初始化 互斥锁 
  64.     //存在警告 pthread_mutexattr_t mutex_attr = PTHREAD_MUTEX_INITIALIZER
  65.      
  66.     if(0 != pthread_mutex_init(&mutex, NULL)) 
  67.     { 
  68.         perror("pthread_mutex_init\n"); 
  69.         exit(1); 
  70.     } 
  71.      
  72.     //初始化信号量 
  73.      
  74.     if(0 != sem_init(&read_sem, 0, 0))//linux进程间的信号共享还未能实现,参数PSHARE为0,而且还没有进行写操作没有数据可读,将参数vaule设置为0,进行阻塞 
  75.     { 
  76.         perror("sem_init_0\n"); 
  77.         exit(1); 
  78.     } 
  79.      
  80.     if(0 != sem_init(&write_sem, 0, 2)) 
  81.     { 
  82.         perror("sem_init_1\n"); 
  83.         exit(1); 
  84.     } 
  85.     //创建两个子线程 
  86.     pthread_t thd0,thd1; 
  87.      
  88.     if(0 != pthread_create(&thd0,NULL,(void*)thread,NULL)) 
  89.     { 
  90.         perror("pthread_create_0\n"); 
  91.         exit(1); 
  92.     } 
  93.      
  94.     if(0 != pthread_create(&thd1,NULL,(void*)thread,NULL)) 
  95.     { 
  96.         perror("pthread_create_1\n"); 
  97.         exit(1); 
  98.     } 
  99.      
  100.     //进行写入字符操作 
  101.     while(1) 
  102.     { 
  103.         //写信号量阻塞 
  104.         if(0 != sem_wait(&write_sem)) 
  105.         { 
  106.             perror("sem_wait_1"); 
  107.             exit(1); 
  108.         } 
  109.         //上互斥锁所进行写入操作 
  110.         if(0 != pthread_mutex_lock(&mutex)) 
  111.         { 
  112.             perror("pthread_mutex_lock_1"); 
  113.             exit(1); 
  114.         } 
  115.          
  116.         fputs("pls enter 20 character:\n",stdout); 
  117.          
  118.         //读标准输入文件 
  119.         if(NULL == fgets(buffer.buf[buffer.rear],STR_SIZE,stdin)) 
  120.         { 
  121.             perror("fgets\n"); 
  122.             exit(1); 
  123.         } 
  124.          
  125.         if(0 == strncmp("end\n",buffer.buf[buffer.rear],3)) 
  126.         { 
  127.             printf("manual exit successfully\n"); 
  128.             exit(1); 
  129.         } 
  130.          
  131.         buffer.rear = (buffer.rear+1)% SIZE; 
  132.         //解互斥锁 
  133.         if(0 != pthread_mutex_unlock(&mutex)) 
  134.         { 
  135.             perror("pthread_mutex_lock_1"); 
  136.             exit(1); 
  137.         } 
  138.          
  139.         if(0 != sem_post(&read_sem)) 
  140.         { 
  141.             perror("sem_wait_1"); 
  142.             exit(1); 
  143.         } 
  144.          
  145.         sleep(1); 
  146.      
  147.     } 
  148.      
  149.      
  150.  
  151.     return 0;