當前位置:編程學習大全網 - 源碼下載 - 在linux下用c語言實現用多進程同步方法演示“生產者-消費者”問題

在linux下用c語言實現用多進程同步方法演示“生產者-消費者”問題

這個問題需要的知識主要包括:

1 多進程間進行通信;

2 使用同步信號量(semaphore)和互斥信號量(mutex)進行數據保護。

參考代碼如下,可以參照註釋輔助理解:

#include?<stdio.h>

#include?<stdlib.h>

#include?<unistd.h>

#include?<pthread.h>

#include?<semaphore.h>

#define?N?2//?消費者或者生產者的數目

#define?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?print()

{

int?i;

for(i?=?0;?i?<?M;?i++)

printf("%d?",?buff[i]);

printf("\n");

}

/*?生產者方法?*/?

void?*product()

{

int?id?=?++product_id;

while(1)

{

//?用sleep的數量可以調節生產和消費的速度,便於觀察

sleep(1);

//sleep(1);

?

sem_wait(&empty_sem);

pthread_mutex_lock(&mutex);

?

in?=?in?%?M;

printf("product%d?in?%d.?like:?\t",?id,?in);

?

buff[in]?=?1;?

print();?

++in;

?

pthread_mutex_unlock(&mutex);

sem_post(&full_sem);?

}

}

/*?消費者方法?*/

void?*prochase()

{

int?id?=?++prochase_id;

while(1)

{

//?用sleep的數量可以調節生產和消費的速度,便於觀察

sleep(1);

//sleep(1);

?

sem_wait(&full_sem);

pthread_mutex_lock(&mutex);

?

out?=?out?%?M;

printf("prochase%d?in?%d.?like:?\t",?id,?out);

?

buff[out]?=?0;

print();

++out;

?

pthread_mutex_unlock(&mutex);

sem_post(&empty_sem);

}

}

int?main()

{

pthread_t?id1[N];

pthread_t?id2[N];

int?i;

int?ret[N];

//?初始化同步信號量

int?ini1?=?sem_init(&empty_sem,?0,?M);?

int?ini2?=?sem_init(&full_sem,?0,?0);?

if(ini1?&&?ini2?!=?0)

{

printf("sem?init?failed?\n");

exit(1);

}?

//初始化互斥信號量?

int?ini3?=?pthread_mutex_init(&mutex,?NULL);

if(ini3?!=?0)

{

printf("mutex?init?failed?\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("product%d?creation?failed?\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("prochase%d?creation?failed?\n",?i);

exit(1);

}

}

//銷毀線程

for(i?=?0;?i?<?N;?i++)

{

pthread_join(id1[i],NULL);

pthread_join(id2[i],NULL);

}

exit(0);?

}

在Linux下編譯的時候,要在編譯命令中加入選項-lpthread以包含多線程支持。比如存儲的C文件為demo.c,要生成的可執行文件為demo。可以使用命令:

gcc demo.c -o demo -lpthread

程序中為便於觀察,使用了sleep(1);來暫停運行,所以查看輸出的時候可以看到,輸出是每秒打印壹次的。

  • 上一篇:躁郁狂潮―—改變心情,迎向美好人生
  • 下一篇:啥?這才單點登錄!
  • copyright 2024編程學習大全網