当前位置:首页 » 操作系统 » 生产者消费者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线程的一个程序,消费者和生产者的例子,应该怎么解释这个程序呢

是啊,在多处理器中线程是可以并行执行的,在单处理器中线程是并发执行的啊,所谓并行执行就是同时执行的啊,并发执行就是简单的说一个一个执行的,由于处理器的速度快,就像一起执行是的,就是并发执行。这两个线程一起运行,就看上面的情况了。如果不明白建议那本操作系统的书看看,或者在网上找进程和线程的网络读。

热点内容
动态规划01背包算法 发布:2024-11-05 22:17:40 浏览:849
nasm编译器如何安装 发布:2024-11-05 22:01:13 浏览:180
登录密码在微信的哪里 发布:2024-11-05 22:00:29 浏览:739
c防止反编译工具 发布:2024-11-05 21:56:14 浏览:247
安卓虚拟机怎么用 发布:2024-11-05 21:52:48 浏览:344
php时间搜索 发布:2024-11-05 20:58:36 浏览:478
燕山大学编译原理期末考试题 发布:2024-11-05 20:13:54 浏览:527
华为电脑出现临时服务器 发布:2024-11-05 20:05:08 浏览:408
斗战神免费挖矿脚本 发布:2024-11-05 19:53:25 浏览:665
网吧服务器分别是什么 发布:2024-11-05 19:45:32 浏览:392