代码如下所示,两边对照查看程序!(左图为先运行进程 右图为后运行进程)
运行的效果就是:当左边的进程检测到EOF,释放资源V操作之后,右边的进程会迅速的执行对应的printf的操作!
所有代码文件结构如下:
sem_a.c(左边进程的代码,编译方式:gcc sem_a.c sempv.c -o sem_a)
#include <stdio.h> #include "sempv.h" int main(int *argc, char *argv[]) { key_t my_key = 1234; int my_sem; my_sem = Create_sem(my_key,1,0666|IPC_CREAT); printf("setting val... "); init_sem(my_sem,0,1); printf("p... "); P(my_sem); while(getchar() != EOF); V(my_sem); sleep(5); del_sem(my_sem); return 0; }
sem_b.c(右边进程的代码,编译方式:gcc sem_b.c sempv.c -o sem_b)
#include<stdio.h> #include "sempv.h" int main(int *argc, char *argv[]) { key_t my_key = 1234; int my_sem; my_sem = Link_sem(my_key,1,0666); printf("p.... "); P(my_sem); printf("sem1 finished! "); V(my_sem); return 0; }
sempv.c(PV操作的源程序,对应函数的实现)
#include "sempv.h" //P操作,申请一个资源 void P(int semid) { struct sembuf my_buf; memset(&my_buf,0,sizeof(my_buf)); my_buf.sem_num = 0; my_buf.sem_op = -1; my_buf.sem_flg = SEM_UNDO; semop(semid,&my_buf,1); } void V(int semid) { struct sembuf my_buf; memset(&my_buf,0,sizeof(my_buf)); my_buf.sem_num = 0; my_buf.sem_op = 1; my_buf.sem_flg = SEM_UNDO; semop(semid,&my_buf,1); } int Create_sem(key_t key,int index,int op) { int sem; sem = semget(key,index,op); if(sem == -1) { printf("semget error! "); exit(1); } return sem; } int Link_sem(key_t key,int index,int op) { int sem; sem = semget(key,index,op); if(sem == -1) { printf("semget error! "); exit(1); } return sem; } void init_sem(int sem,int index,int val) // Provent the sem be lock at the begin of the program! { semctl(sem,index,SETVAL,val); } void del_sem(int sem) { semctl(sem,0,IPC_RMID); }
sempv.h头文件声明
#ifndef __SEMPV_H__ #define __SEMPV_H__ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/sem.h> void P(int semid); void V(int semid); int Link_sem(key_t key,int index,int op); int Create_sem(key_t key,int index,int op); void init_sem(int sem,int index,int val); void del_sem(int sem); #endif
结论:从上述分析中我们可以得知,目前PV操作的库sempv.h/sempv.c的使用步骤如下: