该楼层疑似违规已被系统折叠隐藏此楼查看此楼
操作系统中关于信号量操作的代码示例(Linux+windows)
原文:操作系统中关于信号量操作的代码示例(Linux+windows)
有一个生产者进程,有两个消费者进程。生产者产生1-100的100个数。两个消费者从共享内存中取数。
/*windows部分*/
//Thread.cpp:定义控制台应用程序的入口点。
//-----------Windows下生产者、消费者实例程序---------------------
//--------------author:zhangwei----------------------------------
//--------------Date12/10/---------------------------------
#include"stdafx.h"
//作为仓库存放数据,最多可以放五个数据
intarray[5];
//记录生成数据的个数
intpointer;
//记录取得的数据的位置
intpointerget;
//用来保存数据和
intsum;
//临界区对象
CRITICAL_SECTIONcsArray;
//句柄,保存Full信号量
HANDLEhFull;
//句柄,保存Empty信号量
HANDLEhEmpty;
//生产者函数
DWORDWINAPIProducer(LPVOIDlpParam)
{
inti=0;
pointer=0;
while(i
{
WaitForSingleObject(hEmpty,INFINITE);
EnterCriticalSection(&csArray);
array[(pointer++)%5]=i+1;
LeaveCriticalSection(&csArray);
ReleaseSemaphore(hFull,1,NULL);
i++;
}
return0;
}
//消费者函数A
DWORDWINAPIConsumerA(LPVOIDlpParam)
{
while(1)
{
WaitForSingleObject(hFull,INFINITE);
EnterCriticalSection(&csArray);
sum+=array[(pointerget++)%5];
printf("ConsumerAget%d\n",array[(pointerget-1)%5]);
if(pointerget==100)
printf("Thesumis%d",sum);
LeaveCriticalSection(&csArray);
ReleaseSemaphore(hEmpty,1,NULL);
}
return0;
}
//消费者函数B
DWORDWINAPIConsumerB(LPVOIDlpParam)
{
while(1)
{
WaitForSingleObject(hFull,INFINITE);
EnterCriticalSection(&csArray);
sum+=array[(pointerget++)%5];
printf("ConsumerBget%d\n",array[(pointerget-1)%5]);
if(pointerget==100)
printf("Thesumis%d",sum);
LeaveCriticalSection(&csArray);
ReleaseSemaphore(hEmpty,1,NULL);
}
return0;
}
//主函数
voidmain()
{
HANDLEhThreadProducer,hThreadConsumerA,hThreadComsumerB;
sum=0;
pointerget=0;
InitializeCriticalSection(&csArray);
hFull=CreateSemaphore(NULL,0,5,NULL);
hEmpty=CreateSemaphore(NULL,5,5,NULL);
hThreadProducer=CreateThread(NULL,0,
Producer,NULL,0,NULL);
hThreadConsumerA=CreateThread(NULL,0,
ConsumerA,NULL,0,NULL);
hThreadComsumerB=CreateThread(NULL,0,
ConsumerB,NULL,0,NULL);
_getch();
}
/*Linux部分*/
#include
#include
#include
#include
#include
#include
#include
#include
#defineMAXSEM5
//声明三个信号灯ID
intfullid;
intemptyid;
intmutxid;
intmain()
{
structsembufP,V;;
unionsemunarg;
//声明共享内存
int*array;
int*sum;
int*set;
int*get;
//映射共享内存
array=(int*)mmap(NULL,sizeof(int)*5,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
sum=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
get=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
set=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
*sum=0;
*get=0;
*set=0;
//生成信号灯
fullid=semget(IPC_PRIVATE,1,IPC_CREAT|00666);
emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|00666);
mutxid=semget(IPC_PRIVATE,1,IPC_CREAT|00666);
//为信号灯赋值
arg.val=0;
if(semctl(fullid,0,SETVAL,arg)==-1)perror("semctlsetvalerror");
arg.val=MAXSEM;
if(semctl(emptyid,0,SETVAL,arg)==-1)perror("semctlsetvalerror");
arg.val=1;
if(semctl(mutxid,0,SETVAL,arg)==-1)perror("setctlsetvalerror");
//初始化P,V操作
V.sem_num=0;
V.sem_op=1;
V.sem_flg=SEM_UNDO;
P.sem_num=0;
P.sem_op=-1;
P.sem_flg=SEM_UNDO;
//生产者进程
if(fork()==0){
inti=0;
while(i
{
semop(emptyid,&P,1);
semop(mutxid,&P,1);
array[*(set)%MAXSEM]=i+1;
printf("Producer%d\n",array[(*set)%MAXSEM]);
(*set)++;
semop(mutxid,&V,1);
semop(fullid,&V,1);
i++;
}
sleep(10);
printf("Producerisover");
exit(0);
}else{
//ConsumerA进程
if(fork()==0){
while(1){
semop(fullid,&P,1);
semop(mutxid,&P,1);
if(*get==100)
break;
*sum+=array[(*get)%MAXSEM];
printf("TheComsumerAGetNumber%d\n",array[(*get)%MAXSEM]);
(*get)++;
if(*get==100)
printf("Thesumis%d\n",*sum);
semop(mutxid,&V,1);
semop(emptyid,&V,1);
sleep(1);
}
printf("ConsumerAisover");
exit(0);
}else{
//ConsumerB进程
if(fork()==0){
while(1){
semop(fullid,&P,1);
semop(mutxid,&P,1);
if(*get==100)
break;
*sum+=array[(*get)%MAXSEM];
printf("TheComsumerBGetNumber%d\n",array[(*get)%MAXSEM]);
(*get)++;
if(*get==100)
printf("Thesumis%d\n",*sum);
semop(mutxid,&V,1);
semop(emptyid,&V,1);
sleep(1);
}
printf("ConsumerBisover");
exit(0);
}
}
}
//sleep(20);
return0;
}
我的第一篇文章,多多指教。如需练习mail:dawei_zhang81@