linux 信号灯PV操作

目的

让父子进程通过共享内存来读写数据,父进程负责写,子进程负责读,确保一个进程执行,另一个进程不会执行。

代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#define SEM_READ 0
#define SEM_WRITE 0
union semun
{
        int val;
};
void P(int index,int semid)
{
        struct sembuf sep;
        sep.sem_num = index;
        sep.sem_op = -1;
        sep.sem_flg = 0;
        semop(semid,&sep,1);
}
void V(int index,int semid)
{
        struct sembuf sep;
        sep.sem_num = index;
        sep.sem_op  = 1;
        sep.sem_flg = 0;
        semop(semid,&sep,1);
}
int main()
{
        key_t key;
        int semid;
        int shmid;
        pid_t pid;
        char *p;
        key=ftok("d.c",123);

        semid=semget(key,1,0755|IPC_CREAT);
        if(semid < 0)
        {
                perror("semget");
                return -1;
        }
        shmid=shmget(key,128,0755|IPC_CREAT);
        if(shmid < 0)
        {
                perror("shmget");
                return -2;
        }
        //init semaphore
        union semun myun;
 
        //init semaphore write
        myun.val = 1;
        semctl(semid,SEM_WRITE,SETVAL,myun);
        pid = fork();
        if(pid > 0 )
        {
                while(1)
                {
                        p = (char *)shmat(shmid,NULL,0);
                        P(SEM_WRITE,semid);
                        printf("please input:\n");
                        fgets(p,40,stdin);
                        V(SEM_WRITE,semid);

                }
        }
        else if(pid == 0)
        {
                while(1)
                {
                        p=(char *)shmat(shmid,NULL,0);
                        P(SEM_READ,semid);
                        printf("p===%s\n",p);
                        V(SEM_READ,semid);
                }
        }

        return 0;
}
                                                                                                                                                                                          


执行结果:

请添加图片描述

代码说明

通过ftok函数获取key值,通过shmget来获取共享内存,通过semget函数创建信号灯数量为1的信号灯集,或通semget函数初始化编号为0的信号灯的信号量值为1,用ftok创建父子进程,在子进程和父进程里,分别调用semat函数,使进程里地址映射到共享内存,在父、子进程里,通过PV操作,确保父进程执行写操作的时候,子进程不会执行读操作,子进程执行读操作的时候,父进程不会执行写操作。

P操作使信号量当前值-1,因为这里设置的信号量初始值为1,所以减1,信号量当前值变为0,表示当用资源,
其他进程不能获得资源,要等待执行P操作的进程,使用V操作,是信号量当前值加1,变为1,来释放资源,这
是其他进程才能获取资源。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值