轉自 http://blog.csdn.net/hc260164797/article/details/7566850
該程序爲Linux信號量機制實現程序,主要模擬了一般的生產者-消費者問題。(生產者-消費者問題是一個經典的進程同步問題,該問題最早由Dijkstra提出,用以演示他提出的信號量機制。在同一個進程地址空間內執行的兩個線程。生產者線程生產物品,然後將物品放置在一個空緩衝區中供消費者線程消費。消費者線程從緩衝區中獲得物品,然後釋放緩衝區。當生產者線程生產物品時,如果沒有空緩衝區可用,那麼生產者線程必須等待消費者線程釋放出一個空緩衝區。當消費者線程消費物品時,如果沒有滿的緩衝區,那麼消費者線程將被阻塞,直到新的物品被生產出來。
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <signal.h>
- #define N 5 // 消費者或者生產者的數目
- #define M 10 // 緩衝數目
- //int M=10;
- int in = 0; // 生產者放置產品的位置
- int out = 0; // 消費者取產品的位置
- int buff[M] = { 0 }; // 緩衝初始化爲0,開始時沒有產品
- sem_t empty_sem; // 同步信號量,當滿了時阻止生產者放產品
- sem_t full_sem; // 同步信號量,當沒產品時阻止消費者消費
- pthread_mutex_t mutex; // 互斥信號量,一次只有一個線程訪問緩衝
- int product_id = 0; //生產者id
- int prochase_id = 0; //消費者id
- //信號處理函數
- void Handlesignal(int signo){
- printf("程序退出\n",signo);
- exit(0);
- }
- /* 打印緩衝情況 */
- void print() {
- inti;
- printf("產品隊列爲");
- for(i = 0; i < M; i++)
- printf("%d", buff[i]);
- printf("\n");
- }
- /* 生產者方法 */
- void *product() {
- intid = ++product_id;
- while(1) {//重複進行
- //用sleep的數量可以調節生產和消費的速度,便於觀察
- sleep(2);
- sem_wait(&empty_sem);
- pthread_mutex_lock(&mutex);
- in= in % M;
- printf("生產者%d在產品隊列中放入第%d個產品\t",id, in);
- buff[in]= 1;
- print();
- ++in;
- pthread_mutex_unlock(&mutex);
- sem_post(&full_sem);
- }
- }
- /* 消費者方法 */
- void *prochase() {
- intid = ++prochase_id;
- while(1) {//重複進行
- //用sleep的數量可以調節生產和消費的速度,便於觀察
- sleep(5);
- sem_wait(&full_sem);
- pthread_mutex_lock(&mutex);
- out= out % M;
- printf("消費者%d從產品隊列中取出第%d個產品\t",id, out);
- buff[out]= 0;
- print();
- ++out;
- pthread_mutex_unlock(&mutex);
- sem_post(&empty_sem);
- }
- }
- int main() {
- printf("生產者和消費者數目都爲5,產品緩衝爲10,生產者每2秒生產一個產品,消費者每5秒消費一個產品,Ctrl+退出程序\n");
- pthread_tid1[N];
- pthread_tid2[N];
- inti;
- intret[N];
- //結束程序
- if(signal(SIGINT,Handlesignal)==SIG_ERR){//按ctrl+C產生SIGINT信號
- printf("信號安裝出錯\n");
- }
- // 初始化同步信號量
- intini1 = sem_init(&empty_sem, 0, M);//產品隊列緩衝同步
- intini2 = sem_init(&full_sem, 0, 0);//線程運行同步
- if(ini1 && ini2 != 0) {
- printf("信號量初始化失敗!\n");
- exit(1);
- }
- //初始化互斥信號量
- intini3 = pthread_mutex_init(&mutex, NULL);
- if(ini3 != 0) {
- printf("線程同步初始化失敗!\n");
- exit(1);
- }
- // 創建N個生產者線程
- for(i = 0; i < N; i++) {
- ret[i]= pthread_create(&id1[i], NULL, product, (void *) (&i));
- if(ret[i] != 0) {
- printf("生產者%d線程創建失敗!\n", i);
- exit(1);
- }
- }
- //創建N個消費者線程
- for(i = 0; i < N; i++) {
- ret[i]= pthread_create(&id2[i], NULL, prochase, NULL);
- if(ret[i] != 0) {
- printf("消費者%d線程創建失敗!\n", i);
- exit(1);
- }
- }
- //等待線程銷燬
- for(i = 0; i < N; i++) {
- pthread_join(id1[i], NULL);
- pthread_join(id2[i],NULL);
- }
- exit(0);
- }