一,用信号量来实现是父进程先进行,还是子进程先进性
信号量的没有P,V操作之前,我们不知道如何控制:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>//pid_t fork(void);
//int semget(key_t key, int nsems, int semflg);union semun
{int val; //仅用于SETVAL操作类型,设置某个信号量的值等于valstruct semid_ds *buf; //用于IPC_STAT和IPC_SET操作,存取semid_ds结构unsigned short *array; //用于SETALL和GETALL操作struct seminfo *__buf; //为控制IPC_INFO提供的缓存
};int main()
{key_t key;int semid;key = ftok(".",2);semid = semget(key, 1, IPC_CREAT|0666);union semun initsem;initsem.val = 1;semctl(semid, 0, SETVAL, initsem);int pid = fork();if(pid >0){//get lockprintf("this is father\n");//return lock;}else if(pid == 0){printf("this is child\n");}else{printf("fork error\n");}return 0;
}
有P,V操作:
一开始 val 表示信号量的钥匙为0,fork操作后,先运行父进程,pGetkey(semid); 拿钥匙发现val 为0 卡住,挂起,进而运行子进程,vPutBackKey(semid) ;操作放入钥匙然后再运行父进程。
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>//pid_t fork(void);
//int semget(key_t key, int nsems, int semflg);
//int semop(int semid, struct sembuf *sops, size_t nsops);
//int semctl(int semid, int semnum, int cmd, ...);union semun
{int val; //仅用于SETVAL操作类型,设置某个信号量的值等于valstruct semid_ds *buf; //用于IPC_STAT和IPC_SET操作,存取semid_ds结构unsigned short *array; //用于SETALL和GETALL操作struct seminfo *__buf; //为控制IPC_INFO提供的缓存
};void pGetKey(int id)
{struct sembuf set;set.sem_num = 0;set.sem_op = -1;set.sem_flg = SEM_UNDO;semop(id,&set, 1);printf("getKey\n");
}void vPutBackKey(int id)
{struct sembuf set;set.sem_num = 0;set.sem_op = 1;set.sem_flg = SEM_UNDO;semop(id,&set, 1);printf("put back the key\n");}int main(int argc, char const *argv[])
{key_t key; // 创建id号int semid; //信号量key = ftok(".",2);semid = semget(key, 1, IPC_CREAT|0666);union semun initsem;initsem.val = 0; //信号量的状态标记为0//初始化信号量semctl(semid, 0, SETVAL, initsem); //信号量 操作第0个信号量 //SETVAL 设置信号量的值 设置为 initsemint pid = fork(); //创建子进程if(pid >0){ //父进程pGetKey(semid); //get lockprintf("this is father\n");vPutBackKey(semid); //return lock;}else if(pid == 0){printf("this is child\n");vPutBackKey(semid);}else{printf("fork error\n");}return 0;
}