信号量集控制控制进程读写共享内存

信号量集控制控制进程读写共享内存

#include<stdio.h>
#include<sys/sem.h>
#include<sys/types.h>                                                                                                                                                        
#include<sys/ipc.h>
#include<sys/shm.h>
#include<unistd.h>
#include<string.h>
union semun
{
    int val;
};
int main()
{

    pid_t pid = 0;
    key_t key = ftok("sem_and_shm.c", 1); //以当前文件名为引子获得唯一的键值
    int shmid = shmget(key, sizeof(int), IPC_CREAT|0640); //创建共享内存
    int semid = semget(key, 1, IPC_CREAT|0644); 创建信号量集
    union semun su;
    su.val = 0;  //设置信号量中信号的初值
    if(semctl(semid, 0, SETVAL, su) == -1) //把初值赋给信号量集中的semid号信号
        perror("semctl");

    struct sembuf v[1] = {{0, 1, 0}}; //设置semop操作所需的结构体(加一操作)
    struct sembuf p[1] = {{0, -1, 0}}; //设置semop操作所需的结构体(减一操作)
    if((pid = fork()) == 0) //创建子进程
    {
        char *chp = (char *)shmat(shmid, NULL, 0); //子进程将共享内存映射进自己的虚拟地址空间
        while(1)
        {
            semop(semid, p, 1); //子进程从共享内存中读数据,在读之前进行一次P操作
            printf("读取。。。");
            printf("%s\n", chp);
        }

    }
    else if(pid > 0)
    {
        char *pap = (char *)shmat(shmid, NULL, 0); //父进程将共享内存映射进自己的虚拟地址空间
        while(1)
        {           //父进程不断地往共享内存中写数据,在每次写完后都进行一次V操作
            sleep(1);
            memset(pap, 0, sizeof(pap));
            printf("写入。。\n");
            sprintf(pap, "a");                                        
        }
    }
    else 
        perror("fork");

    return 0;
} 

SEM_UNDO

struct sembuf{
    int sem_num; //第几个信号量
    int sem_op; //P -1,  v +1
    int sem_flag; //0006
};

当操作信号量(semop)时,semop函数中第二个参数struct sembuf中,sem_flg可以设置SEM_UNDO标识;SEM_UNDO用于将修改的信号量值在进程正常退出(调用exit退出或main执行完)或异常退出(如段异常、除0异常、收到KILL信号等)时归还给信号量。
 
如信号量初始值是20,进程以SEM_UNDO方式操作信号量减2,减5,加1;在进程未退出时,信号量变成20-2-5+1=14;在进程退出时,将修改的值归还给信号量,信号量变成14+2+5-1=20。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值