一,用信号量来实现是父进程先进行,还是子进程先进性
信号量的没有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操作类型,设置某个信号量的值等于val
struct 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 lock
printf("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操作类型,设置某个信号量的值等于val
struct 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 设置信号量的值 设置为 initsem
int pid = fork(); //创建子进程
if(pid >0){ //父进程
pGetKey(semid); //get lock
printf("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;
}