當前位置:首頁 » 操作系統 » 生產者消費者linux

生產者消費者linux

發布時間: 2022-04-26 23:17:30

『壹』 在linux下,用QT實現生產者與消費者關系的實例

定義一個QList鏈表,
生產者不斷地將數據添加到QList的隊尾,
消費者不斷去詢問QList是否為空,如為空則等待,否則就獲取QList隊頭第一個數據。
如此就是一個簡單的生產者與消費者關系
如果要完善一下,則需要添加一個信號量來管理QList的刪除和添加操作,防止出現錯誤

『貳』 在linux下,處理生產者消費者問題時,生產者完全可以在完成生產任務之後退出,但為什麼一旦退出就會死機

display(Buffer);
tail++;
count++;
cout<<"按ENTER繼續...."<<endl;
ch=getchar();
ReleaseMutex(hMutex); //結束臨界區
PulseEvent(hNotEmptyEvent); //喚醒消費者線程
}
}
}
}
//////////////////////////////////////////////////////////////////
//p2

『叄』 linux怎麼打開生產者消費者問題

這個問題需要的知識主要包括: 1 多進程間進行通信; 2 使用同步信號量(semaphore)和互斥信號量(mutex)進行數據保護。 參考代碼如下,可以參照注釋輔助理解: #include #include #include #include #include #define

『肆』 進程的同步與互斥實驗報告Linux

相交進程之間的關系主要有兩種,同步與互斥。所謂互斥,是指散步在不同進程之間的若干程序片斷,當某個進程運行其中一個程序片段時,其它進程就不能運行它 們之中的任一程序片段,只能等到該進程運行完這個程序片段後才可以運行。所謂同步,是指散步在不同進程之間的若干程序片斷,它們的運行必須嚴格按照規定的 某種先後次序來運行,這種先後次序依賴於要完成的特定的任務。
顯然,同步是一種更為復雜的互斥,而互斥是一種特殊的同步。
也就是說互斥是兩個線程之間不可以同時運行,他們會相互排斥,必須等待一個線程運行完畢,另一個才能運行,而同步也是不能同時運行,但他是必須要安照某種次序來運行相應的線程(也是一種互斥)!
總結:互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。
同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源

『伍』 生產者消費者問題--進程

#i nclude<stdio.h>
#i nclude< iostream.h>
#i nclude< windows.h>
#define BufferSize 15
char Buffer[BufferSize];
int head,tail=0;//Buffer數組下標
int count;//被使用的緩沖區數量
HANDLE hMutex;
HANDLE hNotFullEvent, hNotEmptyEvent;//用來同步生產者和消費者線程
////////緩沖區存儲情況
display(char a[15])
{
int i;
cout<<"緩沖區存儲情況為:"<<endl;
for (i=14;i>=0;i--){
cout<<"\t|----"<<a<<"----|"<<endl;
}
}

//p1
void p1_Procer()
{
int i;
char ch;
char p1[]={'a','A','b','B','c','C','D','d','E','e'};
if(tail<15){
for(i=0;i<10;i++){
while(1) {

WaitForSingleObject(hMutex,INFINITE);
if(count==BufferSize){ //緩沖區滿
ReleaseMutex(hMutex);
//等待直到緩沖區非滿
WaitForSingleObject(hNotFullEvent,INFINITE);
continue;
}
//得到互斥鎖且緩沖區非滿,跳出while循環
break;

}
if (tail>14){
cout<<"緩沖區已滿,不能再存入數據!"<<endl;
ReleaseMutex(hMutex); //結束臨界區
PulseEvent(hNotEmptyEvent); //喚醒消費者線程
}
else{
//得到互斥鎖且緩沖區非滿,開始產生新數據
cout<<"Procer p1:\t"<<p1<<endl;
Buffer[tail]=p1;
//tail=(tail+1)%BufferSize;///存放於緩沖區的位置
display(Buffer);
tail++;
count++;
cout<<"按ENTER繼續...."<<endl;
ch=getchar();
ReleaseMutex(hMutex); //結束臨界區
PulseEvent(hNotEmptyEvent); //喚醒消費者線程
}
}
}
}
//////////////////////////////////////////////////////////////////
//p2
void p2_Procer()
{
int i;
char ch;
char p2[]={'0','1','2','3','4','5','6','7','8','9'};
if(tail<15){
for(i=0;i<10;i++){
while(1) {
ch=getchar();
WaitForSingleObject(hMutex,INFINITE);
if(count==BufferSize){ // 緩沖區滿
ReleaseMutex(hMutex);
// 等待直到緩沖區非滿
WaitForSingleObject(hNotFullEvent,INFINITE);
continue;
}
// 得到互斥鎖且緩沖區非滿,跳出while循環
break;
}
if (tail>14){
cout<<"緩沖區已滿,不能再存入數據!程序結束!"<<endl;
ReleaseMutex(hMutex); //結束臨界區
PulseEvent(hNotEmptyEvent); //喚醒消費者線程
}
else{
// 得到互斥鎖且緩沖區非滿,開始產生新數據
cout<<"Procer p2:\t"<<p2<<endl;
Buffer[tail]=p2;
//tail=(tail+1)%BufferSize;
display(Buffer);
tail++;
count++;
cout<<"按ENTER繼續...."<<endl;

ch=getchar();
ReleaseMutex(hMutex); // 結束臨界區
PulseEvent(hNotEmptyEvent); // 喚醒消費者線程
}
}
}
}
//////////////////////////////////////////////////////////////////
//p3
void p3_Procer()
{
int i;
char ch;
char p3[]={'!','#','$','%','&','*','+','-','.','/'};
if(tail<15){
for(i=0;i<10;i++){
while(1) {
ch=getchar();
WaitForSingleObject(hMutex,INFINITE);
if(count==BufferSize){ // 緩沖區滿
ReleaseMutex(hMutex);
// 等待直到緩沖區非滿
WaitForSingleObject(hNotFullEvent,INFINITE);
continue;
}
// 得到互斥鎖且緩沖區非滿,跳出while循環
break;
}
if (tail>14){
cout<<"緩沖區已滿,不能再存入數據!程序結束!"<<endl;
ReleaseMutex(hMutex); //結束臨界區
PulseEvent(hNotEmptyEvent); //喚醒消費者線程
}
else{
// 得到互斥鎖且緩沖區非滿,開始產生新數據
cout<<"Procer p3:\t"<<p3<<endl;
Buffer[tail]=p3;
//tail=(tail+1)%BufferSize;
display(Buffer);
tail++;
count++;
cout<<"按ENTER繼續...."<<endl;

ch=getchar();
ReleaseMutex(hMutex); // 結束臨界區
PulseEvent(hNotEmptyEvent); // 喚醒消費者線程
}
}
}
}
//////////////////////////////////////////////////////////////////
//c1
void c1_Consumer()
{
int i,j,k;
char result,ch;
while(1){
ch=getchar();
WaitForSingleObject(hMutex,INFINITE);
if(count==0){ // 沒有可以處理的數據
ReleaseMutex(hMutex); // 釋放互斥鎖且等待
// 等待直到緩沖區非空
WaitForSingleObject(hNotEmptyEvent,INFINITE);
}
else {if(Buffer[head]==0) {
cout<<"Consumer 0: 緩沖區的數據已全消費過一次,消費完畢!"<<endl;

ReleaseMutex(hMutex); // 結束臨界區
ExitThread(0);
}
else { // 獲得互斥鎖且緩沖區有數據,開始處理
result=Buffer[head];
if(result>64&&result<70){
result=result+32;
cout<<"Consumer c1:(大寫->小寫)\t "<<result<<endl;
Buffer[head]='^';// '^'表示數據已被消費
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);
}

if(result>96&&result<102){
result=result-32;
cout<<"Consumer c1:(小寫->大寫)\t "<<result<<endl;
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);
}
if(result>47&&result<58){
cout<<"Consumer c1:(顯示字元)\t "<<result<<endl;
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);}
if(result>32&&result<48){
cout<<"Consumer c1:(用符號列印出菱形) "<<endl;
for(i=1;i<=(9+1)/2;i++)
{
for(j=1;j<=40-i;j++)
cout<<" ";
for(k=1;k<=2*i-1;k++)
cout<<result;
cout<<endl;
}
for(i=1;i<=9/2;i++)
{
for(j=1;j<=40-(9+1)/2+i;j++)
cout<<" ";
for(k=1;k<=9-2*i;k++)
cout<<result;
cout<<endl;
}
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);
}

head=(head+1)%BufferSize;
count--;
cout<<"按ENTER繼續...."<<endl;

ch=getchar();
ReleaseMutex(hMutex); // 結束臨界區
PulseEvent(hNotFullEvent); // 喚醒生產者線程
}
}
}
}
//////////////////////////////////////////////////////////////////
//c2
void c2_Consumer()
{
int i,j,k;
char result,ch;
while(1){
WaitForSingleObject(hMutex,INFINITE);
if(count==0){ // 沒有可以處理的數據
ReleaseMutex(hMutex); // 釋放互斥鎖且等待
// 等待直到緩沖區非空
WaitForSingleObject(hNotEmptyEvent,INFINITE);
}
else {if(Buffer[head]==0) {
cout<<"Consumer 0:緩沖區的數據已全消費過一次,消費完畢!"<<endl;
ReleaseMutex(hMutex); // 結束臨界區
ExitThread(0);
}
else { // 獲得互斥鎖且緩沖區有數據,開始處理
result=Buffer[head];
if(result>64&&result<90){
result=result+32;
cout<<"Consumer c2:(大寫->小寫)\t "<<result<<endl;
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);
}

if(result>96&&result<102){
result=result-32;
cout<<"Consumer c2:(小寫->大寫)\t "<<result<<endl;
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);}
if(result>47&&result<58){
cout<<"Consumed c2:(顯示字元)\t "<<result<<endl;
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);}
if(result>32&&result<48){
cout<<"Consumer c2:(用符號列印出菱形) "<<endl;
for(i=1;i<=(9+1)/2;i++)
{
for(j=1;j<=40-i;j++)
cout<<" ";
for(k=1;k<=2*i-1;k++)
cout<<result;
cout<<endl;
}
for(i=1;i<=9/2;i++)
{
for(j=1;j<=40-(9+1)/2+i;j++)
cout<<" ";
for(k=1;k<=9-2*i;k++)
cout<<result;
cout<<endl;
}
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);
}

head=(head+1)%BufferSize;
count--;
cout<<"按ENTER繼續...."<<endl;
ch=getchar();
ReleaseMutex(hMutex); // 結束臨界區
PulseEvent(hNotFullEvent); // 喚醒生產者線程
}
}
}
}
//////////////////////////////////////////////////////////////////
//c3
void c3_Consumer()
{
int i,j,k;
char result,ch;
while(1){
WaitForSingleObject(hMutex,INFINITE);
if(count==0){ // 沒有可以處理的數據
ReleaseMutex(hMutex); // 釋放互斥鎖且等待
// 等待直到緩沖區非空
WaitForSingleObject(hNotEmptyEvent,INFINITE);
}
else {if(Buffer[head]==0) {
cout<<"Consumer 0: 緩沖區的數據已全消費過一次,消費完畢!"<<endl;
ReleaseMutex(hMutex); // 結束臨界區
ExitThread(0);
}
else { // 獲得互斥鎖且緩沖區有數據,開始處理
result=Buffer[head];
if(result>64&&result<70){
result=result+32;
cout<<"Consumer c3:(大寫->小寫)\t "<<result<<endl;
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);}

if(result>96&&result<102){
result=result-32;
cout<<"Consumer c3:(小寫->大寫)\t "<<result<<endl;
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);}
if(result>47&&result<58){
cout<<"Consumer c1:(顯示字元)\t "<<result<<endl;
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);
}
if(result>32&&result<48){
cout<<"Consumer c3:(用符號列印出菱形) "<<endl;
for(i=1;i<=(7+1)/2;i++)
{
for(j=1;j<=40-i;j++)
cout<<" ";
for(k=1;k<=2*i-1;k++)
cout<<result;
cout<<endl;
}
for(i=1;i<=7/2;i++)
{
for(j=1;j<=40-(7+1)/2+i;j++)
cout<<" ";
for(k=1;k<=7-2*i;k++)
cout<<result;
cout<<endl;
}
Buffer[head]='^';
cout<<"'^'表示數據已被消費"<<endl;
display(Buffer);
}
head=(head+1)%BufferSize;
count--;
cout<<"按ENTER繼續...."<<endl;

ch=getchar();
ReleaseMutex(hMutex); // 結束臨界區
PulseEvent(hNotFullEvent); // 喚醒生產者線程
}
}
}
}
//////////////////////////////////////////////////////////////////
//主函數
void main()
{
HANDLE hThreadVector[6];
DWORD ThreadID;
count = 0;
head = 0;
tail = 0;
hMutex=CreateMutex(NULL,FALSE,NULL);
hNotFullEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
hNotEmptyEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
hThreadVector[0]=CreateThread (NULL, 0,(LPTHREAD_START_ROUTINE) p1_Procer,NULL, 0, (LPDWORD)&ThreadID);
hThreadVector[1]=CreateThread (NULL, 0,(LPTHREAD_START_ROUTINE) c1_Consumer,NULL, 0, (LPDWORD)&ThreadID);
hThreadVector[3]=CreateThread (NULL, 0,(LPTHREAD_START_ROUTINE) p2_Procer,NULL, 0, (LPDWORD)&ThreadID);
hThreadVector[4]=CreateThread (NULL, 0,(LPTHREAD_START_ROUTINE) c2_Consumer,NULL, 0, (LPDWORD)&ThreadID);
hThreadVector[5]=CreateThread (NULL, 0,(LPTHREAD_START_ROUTINE) p3_Procer,NULL, 0, (LPDWORD)&ThreadID);
hThreadVector[5]=CreateThread (NULL, 0,(LPTHREAD_START_ROUTINE) c3_Consumer,NULL, 0, (LPDWORD)&ThreadID);
WaitForMultipleObjects(2,hThreadVector,TRUE,INFINITE);
//cout<<"**********************Finish*************************"<<endl;
}

我最近也在學操作系統,PV好麻煩的

『陸』 求教Linux下gcc編譯生產者消費者問題 #include <stdio.h> gcc編譯時出錯 錯誤如下圖

報錯是因為你使用的函數沒有聲明,缺少頭文件,所以加上頭文件就ok了
包含頭文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

『柒』 在linux下用c語言實現用多進程同步方法演示「生產者-消費者」問題

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

1 多進程間進行通信;

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

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

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>
#defineN2//消費者或者生產者的數目
#defineM10//緩沖數目
intin=0;//生產者放置產品的位置
intout=0;//消費者取產品的位置
intbuff[M]={0};//緩沖初始化為0,開始時沒有產品
sem_tempty_sem;//同步信號量,當滿了時阻止生產者放產品
sem_tfull_sem;//同步信號量,當沒產品時阻止消費者消費
pthread_mutex_tmutex;//互斥信號量,一次只有一個線程訪問緩沖
intproct_id=0;//生產者id
intprochase_id=0;//消費者id
/*列印緩沖情況*/
voidprint()
{
inti;
for(i=0;i<M;i++)
printf("%d",buff[i]);
printf(" ");
}
/*生產者方法*/
void*proct()
{
intid=++proct_id;

while(1)
{
//用sleep的數量可以調節生產和消費的速度,便於觀察
sleep(1);
//sleep(1);

sem_wait(&empty_sem);
pthread_mutex_lock(&mutex);

in=in%M;
printf("proct%din%d.like: ",id,in);

buff[in]=1;
print();
++in;

pthread_mutex_unlock(&mutex);
sem_post(&full_sem);
}
}
/*消費者方法*/
void*prochase()
{
intid=++prochase_id;
while(1)
{
//用sleep的數量可以調節生產和消費的速度,便於觀察
sleep(1);
//sleep(1);

sem_wait(&full_sem);
pthread_mutex_lock(&mutex);

out=out%M;
printf("prochase%din%d.like: ",id,out);

buff[out]=0;
print();
++out;

pthread_mutex_unlock(&mutex);
sem_post(&empty_sem);
}
}
intmain()
{
pthread_tid1[N];
pthread_tid2[N];
inti;
intret[N];

//初始化同步信號量
intini1=sem_init(&empty_sem,0,M);
intini2=sem_init(&full_sem,0,0);
if(ini1&&ini2!=0)
{
printf("seminitfailed ");
exit(1);
}
//初始化互斥信號量
intini3=pthread_mutex_init(&mutex,NULL);
if(ini3!=0)
{
printf("mutexinitfailed ");
exit(1);
}
//創建N個生產者線程
for(i=0;i<N;i++)
{
ret[i]=pthread_create(&id1[i],NULL,proct,(void*)(&i));
if(ret[i]!=0)
{
printf("proct%dcreationfailed ",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%dcreationfailed ",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);來暫停運行,所以查看輸出的時候可以看到,輸出是每秒列印一次的。

『捌』 求助,關於linux的線程同步問題

【Linux多線程】三個經典同步問題
標簽: 多線程同步生產者與消費者寫者與讀者

目錄(?)[+]
在了解了《同步與互斥的區別 》之後,我們來看看幾個經典的線程同步的例子。相信通過具體場景可以讓我們學會分析和解決這類線程同步的問題,以便以後應用在實際的項目中。
一、生產者-消費者問題
問題描述:
一組生產者進程和一組消費者進程共享一個初始為空、大小為 n 的緩沖區,只有緩沖區沒滿時,生產者才能把消息放入到緩沖區,否則必須等待;只有緩沖區不空時,消費者才能從中取出消息,否則必須等待。由於緩沖區是臨界資源,它只允許一個生產者放入消息,或者一個消費者從中取出消息。
分析:
關系分析:生產者和消費者對緩沖區互斥訪問是互斥關系,同時生產者和消費者又是一個相互協作的關系,只有生產者生產之後,消費者才能消費,它們也是同步關系。
整理思路:這里比較簡單,只有生產者和消費者兩個進程,且這兩個進程存在著互斥關系和同步關系。那麼需要解決的是互斥和同步的PV操作的位置。
信號量設置:信號量mutex作為互斥信號量,用於控制互斥訪問緩沖池,初值為1;信號量full用於記錄當前緩沖池中「滿」緩沖區數,初值為 0;信號量empty用於記錄當前緩沖池中「空」緩沖區數,初值為n。
代碼示例:(semaphore類的封裝見下文)
#include<iostream>
#include<unistd.h> // sleep
#include<pthread.h>
#include"semaphore.h"
using namespace std;
#define N 5

semaphore mutex("/", 1); // 臨界區互斥信號量
semaphore empty("/home", N); // 記錄空緩沖區數,初值為N
semaphore full("/home/songlee",0); // 記錄滿緩沖區數,初值為0
int buffer[N]; // 緩沖區,大小為N
int i=0;
int j=0;

void* procer(void* arg)
{
empty.P(); // empty減1
mutex.P();

buffer[i] = 10 + rand() % 90;
printf("Procer %d write Buffer[%d]: %d\n",arg,i+1,buffer[i]);
i = (i+1) % N;

mutex.V();
full.V(); // full加1
}

void* consumer(void* arg)
{
full.P(); // full減1
mutex.P();

printf(" \033[1;31m");
printf("Consumer %d read Buffer[%d]: %d\n",arg,j+1,buffer[j]);
printf("\033[0m");
j = (j+1) % N;

mutex.V();
empty.V(); // empty加1
}

int main()
{
pthread_t id[10];

// 開10個生產者線程,10個消費者線程
for(int k=0; k<10; ++k)
pthread_create(&id[k], NULL, procer, (void*)(k+1));

for(int k=0; k<10; ++k)
pthread_create(&id[k], NULL, consumer, (void*)(k+1));

sleep(1);
return 0;
}

編譯運行輸出結果:
Procer 1 write Buffer[1]: 83
Procer 2 write Buffer[2]: 26
Procer 3 write Buffer[3]: 37
Procer 5 write Buffer[4]: 35
Procer 4 write Buffer[5]: 33
Consumer 1 read Buffer[1]: 83
Procer 6 write Buffer[1]: 35
Consumer 2 read Buffer[2]: 26
Consumer 3 read Buffer[3]: 37
Consumer 4 read Buffer[4]: 35
Consumer 5 read Buffer[5]: 33
Consumer 6 read Buffer[1]: 35
Procer 7 write Buffer[2]: 56
Procer 8 write Buffer[3]: 22
Procer 10 write Buffer[4]: 79
Consumer 9 read Buffer[2]: 56
Consumer 10 read Buffer[3]: 22
Procer 9 write Buffer[5]: 11
Consumer 7 read Buffer[4]: 79
Consumer 8 read Buffer[5]:

二、讀者-寫者問題
問題描述:
有讀者和寫者兩組並發線程,共享一個文件,當兩個或以上的讀線程同時訪問共享數據時不會產生副作用,但若某個寫線程和其他線程(讀線程或寫線程)同時訪問共享數據時則可能導致數據不一致的錯誤。因此要求:
允許多個讀者可以同時對文件執行讀操作;
只允許一個寫者往文件中寫信息;
任一寫者在完成寫操作之前不允許其他讀者或寫者工作;
寫者執行寫操作前,應讓已有的讀者和寫者全部退出。
分析:
關系分析:由題目分析可知,讀者和寫者是互斥的,寫者和寫者也是互斥的,而讀者和讀者不存在互斥問題。
整理思路:寫者是比較簡單的,它與任何線程互斥,用互斥信號量的 PV 操作即可解決。讀者的問題比較復雜,它必須實現與寫者的互斥,多個讀者還可以同時讀。所以,在這里用到了一個計數器,用它來判斷當前是否有讀者讀文件。當有讀者的時候寫者是無法寫文件的,此時讀者會一直佔用文件,當沒有讀者的時候寫者才可以寫文件。同時,不同的讀者對計數器的訪問也應該是互斥的。
信號量設置:首先設置一個計數器count,用來記錄當前的讀者數量,初值為0;設置互斥信號量mutex,用於保護更新 count 變數時的互斥;設置互斥信號量rw用於保證讀者和寫者的互斥訪問。
代碼示例:
#include<iostream>
#include<unistd.h> // sleep
#include<pthread.h>
#include"semaphore.h"
using namespace std;

int count = 0; // 記錄當前的讀者數量
semaphore mutex("/",1); // 用於保護更新count變數時的互斥
semaphore rw("/home",1); // 用於保證讀者和寫者的互斥

void* writer(void* arg)
{
rw.P(); // 互斥訪問共享文件

printf(" Writer %d start writing...\n", arg);
sleep(1);
printf(" Writer %d finish writing...\n", arg);

rw.V(); // 釋放共享文件
}

void* reader(void* arg)
{
mutex.P(); // 互斥訪問count變數
if(count == 0) // 當第一個讀線程讀文件時
rw.P(); // 阻止寫線程寫
++count; // 讀者計數器加1
mutex.V(); // 釋放count變數

printf("Reader %d start reading...\n", arg);
sleep(1);
printf("Reader %d finish reading...\n", arg);

mutex.P(); // 互斥訪問count變數
--count; // 讀者計數器減1
if(count == 0) // 當最後一個讀線程讀完文件
rw.V(); // 允許寫線程寫
mutex.V(); // 釋放count變數
}

int main()
{
pthread_t id[8]; // 開6個讀線程,2個寫線程

pthread_create(&id[0], NULL, reader, (void*)1);
pthread_create(&id[1], NULL, reader, (void*)2);

pthread_create(&id[2], NULL, writer, (void*)1);
pthread_create(&id[3], NULL, writer, (void*)2);

pthread_create(&id[4], NULL, reader, (void*)3);
pthread_create(&id[5], NULL ,reader, (void*)4);
sleep(2);
pthread_create(&id[6], NULL, reader, (void*)5);
pthread_create(&id[7], NULL ,reader, (void*)6);

sleep(4);
return 0;
}555657585960

編譯運行的結果如下:
Reader 2 start reading...
Reader 1 start reading...
Reader 3 start reading...
Reader 4 start reading...
Reader 1 finish reading...
Reader 2 finish reading...
Reader 3 finish reading...
Reader 4 finish reading...
Writer 1 start writing...
Writer 1 finish writing...
Writer 2 start writing...
Writer 2 finish writing...
Reader 5 start reading...
Reader 6 start reading...
Reader 5 finish reading...
Reader 6 finish reading...

三、哲學家進餐問題
問題描述:
一張圓桌上坐著 5 名哲學家,桌子上每兩個哲學家之間擺了一根筷子,桌子的中間是一碗米飯,如圖所示:

哲學家們傾注畢生精力用於思考和進餐,哲學家在思考時,並不影響他人。只有當哲學家飢餓的時候,才試圖拿起左、右兩根筷子(一根一根拿起)。如果筷子已在他人手上,則需等待。飢餓的哲學家只有同時拿到了兩根筷子才可以開始進餐,當進餐完畢後,放下筷子繼續思考。
分析:
關系分析:5名哲學家與左右鄰居對其中間筷子的訪問是互斥關系。
整理思路:顯然這里有 5 個線程,那麼要如何讓一個哲學家拿到左右兩個筷子而不造成死鎖或飢餓現象?解決方法有兩個,一個是讓他們同時拿兩個筷子;二是對每個哲學家的動作制定規則,避免飢餓或死鎖現象的發生。
信號量設置:定義互斥信號量數組chopstick[5] = {1,1,1,1,1}用於對 5 根筷子的互斥訪問。
示例代碼:

『玖』 關於LInux線程的一個程序,消費者和生產者的例子,應該怎麼解釋這個程序呢

是啊,在多處理器中線程是可以並行執行的,在單處理器中線程是並發執行的啊,所謂並行執行就是同時執行的啊,並發執行就是簡單的說一個一個執行的,由於處理器的速度快,就像一起執行是的,就是並發執行。這兩個線程一起運行,就看上面的情況了。如果不明白建議那本操作系統的書看看,或者在網上找進程和線程的網路讀。

熱點內容
消滅病毒三百關後用什麼伺服器 發布:2024-10-04 00:57:56 瀏覽:479
什麼叫php 發布:2024-10-04 00:57:23 瀏覽:30
如何製作ftp伺服器 發布:2024-10-04 00:49:33 瀏覽:582
androidfragment選項卡 發布:2024-10-04 00:38:03 瀏覽:365
和平精英如何用密碼登錄安卓 發布:2024-10-04 00:27:44 瀏覽:904
安卓手機資料怎麼上傳電腦 發布:2024-10-04 00:18:42 瀏覽:312
led燈編程 發布:2024-10-03 23:59:25 瀏覽:157
怎麼改建行卡密碼 發布:2024-10-03 23:39:03 瀏覽:915
優盤加密解除 發布:2024-10-03 23:29:09 瀏覽:654
讀書郎雙清密碼是多少 發布:2024-10-03 23:23:52 瀏覽:119