临界区:访问临界资源的代码
临界资源:同一时刻只允许一个进程访问的资源
p:获取资源
v:释放资源
前台只能执行一个进程,后台可以执行多个所以a和b程序必须得放在后台,结果还是在前台显示
a程序 #include#include #include #include #include #include 信号量头文件 static int semid=-1; union semun { int val; }; void sem_init()创建 { semid=semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600); 两个进程同一个key_t,代表一个信号量,1代表1个信号量 创建|确保第一个创建(创建的得初始化)| 访问权限 if(semid==-1)失败,说明已有人创建 { semid=semget((key_t)1234,1,0600);获取 if(semid==-1) { printf("semid errn"); return; } }else { 全新创建成功,现在初始化 union semun a; a.val=1; if(semctl(semid,0,SETVAL,a)==-1)失败 { 0表示对第几个信号量初始化,SETVAL将a的值赋给信号量 printf("semctl errn"); } } } void sem_p() { struct sembuf buf; buf.sem_num=0;对第0个信号量进行操作 buf.sem_op()=-1;值减1 buf.sem_flg=SEM_UNDO;当程序不小心结束后,帮忙释放信号量 if(semop(semid,&buf,1)==-1)1组信号量 { printf("semop p errn"); } } void sem_v() { struct sembuf buf; buf.sem_num=0;对第0个信号量进行操作 buf.sem_op()=1;值加1 buf.sem_flg=SEM_UNDO;当程序不小心结束后,帮忙释放信号量 if(semop(semid,&buf,1)==-1)1个结构体变量 { printf("semop v errn"); } } void sem_destory() { if(semctl(semid,0,IPC_RMID)==-1)删除信号量 { printf("semctl err destoryn"); } } int main() { sem_init(); for(int i=0;i<5;++i) { sem_p();p操作 printf("A"); fflush(stdout); int n=rand()%3; sleep(n); printf("A"); fflush(stdout); sem_v();v操作 n=rand()%3; sleep(n); } sleep(10); sem_destory(); } b程序 #include #include #include #include #include int main() { for(int i=0;i>5;++i) { sem_init(); sem_p(); printf("A"); fflush(stdout); int n=rand()%3; sleep(n); printf("A"); fflush(stdout); sem_v(); n=rand()%3; sleep(n); } } 结果为AABBAABBAABB或BBAABBAABBAA
让三个进程打印ABCABCABC,得设置三个信号量,s1(0),s2(1),s3(1)
#include#include #include #include #define SEM_NUM 3共设置三个信号量 #define SEM1 0三个信号量名 #define SEN2 1 #define SEN3 2 static int semid=-1; union semun { int val; } void sem_init() { semid=semget((key_t)1234,SEN_NUM,IPC_CREAT|IPC_EXCL|0600); if(semid==-1) { semid=semget((key_t)1234,SEM_NUM,0600); }else { int arr[SEM_NUM]={1,0,0}; for(int i=0;i =SEM_NUM) { return; } struct sembuf buf; buf.sem_num=index; buf.sem_op=-1; buf.sem_flg=SEM_UNDO; if(semop(semid,&buf,1)==-1) { return ; } } void sem_v(int index) { if(index<0||index>=SEM_NUM) { return; } struct sembuf buf; buf.sem_num=index; buf.sem_op=1; buf.sem_flg=SEM_UNDO; if(semop(semid,&buf,1)==-1) { return ; } } void sem_destory() { if(semctl(semid,0,IPC_RMID)==-1) { return; } } int main() { int res=sem_init(); if(res==-1) { return 0; } for(int i=0;i<5;++i) { sem_p(SEM1); printf("A"); fflush(stdout); sem_v(SEM2); } } int main() { int res=sem_init(); if(res==-1) { return 0; } for(int i=0;i<5;++i) { sem_p(SEM1); printf("B"); fflush(stdout); sem_v(SEM2); } } int main() { int res=sem_init(); if(res==-1) { return 0; } for(int i=0;i<5;++i) { sem_p(SEM2); printf("C"); fflush(stdout); sem_v(SEM0); } sem_destory(); }
ipcs:可以查看共享内存,消息队列,信号量
共享内存共享内存:内存中有一块既可以被A进程使用,B也可以使用
1.创建共享内存
2.将共享内存映射到进程中
3.断开映射
4.删除映射
ipcs -m只看共享内存
ipcs -q只看消息队列
ipcs -s只看信号量
#include#include #include #include #include #include a程序写 int main() { int shmid=shmget((key_t)1234,128,IPC_CREAT|0600); 128共享内存的大小 assert(shmid!=-1); char* s=(char*)shmat(shmid.NULL,0);NULL代表由操统自行分配空间,0默认读写都可 while(1) { printf("input:n"); char buff[128]={0}; fgets(buff,128,stdin); sem_p(SEM0); strcpy(s,buff);像共享内存中写入hello sem_v(SEM1); if(strncmp(buff,"end",3)==0) { break; } } shmdt(s);断开映射 } b程序读 int main() { int shmid=shmget((key_t)1234,128,IPC_CREAT|0600); 128共享内存的大小 assert(shmid!=-1); char* s=(char*)shmat(shmid,NULL,0);NULL代表由操统自行分配空间,0默认读写都可 while(1) { sem_p(SEM2); if(strncmp(s,"end",3)==0) { break; } printf("read:%sn",s); sem_v(SEM1); } shmdt(s);断开映射 shmctl(shmid,IPC_RMID,NULL);删除共享内存 sem_destroy(); }
ipcrm -s +标识符:删除信号量
ipcrm -m +标识符:删除共享内存



