Linux信号量的编程

一,用信号量来实现是父进程先进行,还是子进程先进性

信号量的没有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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值