Linux进程通信——信号量

/*
 * 进程间通信之信号量,代码源自《Linux程序设计》
 */
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
// 使用信号量必须包含该文件
#include <sys/sem.h>

using namespace std;

// 自定义的一个联合体,信号量相关函数需要使用
union semun
{
    int val;
    struct semid_ds* buf;
    unsigned short* array;
};

// 初始化信号量
int set_semvalue(int semid)
{
    union semun sem_union;
    // 信号量的初始值是1
    sem_union.val = 1;

    // 使用semctl函数去设置它,参数为SETVAL
    if(semctl(semid,0,SETVAL,sem_union) == -1)
    {
        cout << "set_semvalue failed!"<< endl;
        return 0;
    }
    return 1;
}

// 删除一个信号量
int del_semvalue(int semid)
{
    union semun sem_union;
    // 使用semctl去删除它,标志是IPC_RMID
    if(semctl(semid,0,IPC_RMID,sem_union) == -1)
    {
        cout << "del_semvalue failed!"<< endl;
        return 0;
    }

    return 1;
}

// 等待信号量
int semaphore_p(int semid)
{
    struct sembuf sem_b;

    sem_b.sem_num = 0;  // 如果不是使用一组信号,那么这个值一般都是0
    sem_b.sem_op = -1;    // 表示进行P操作
    sem_b.sem_flg = SEM_UNDO; // 默认都要设置为SEM_UNDO(这是为了,当进程异常退出的时候,系统可以释放进程持有的信号量)
    // 调用semop进行P操作
    if(semop(semid,&sem_b,1) == -1)
    {
         cout << "semaphore_p failed!"<< endl;
        return 0;
    }

    return 1;
}

// V操作,释放信号量
int semaphore_v(int semid)
{
    struct sembuf sem_b;

    sem_b.sem_num = 0;
    sem_b.sem_op = 1;   // 1表示进行V操作
    sem_b.sem_flg = SEM_UNDO;

    if(semop(semid,&sem_b,1) == -1)
    {
         cout << "semaphore_v failed!"<< endl;
        return 0;
    }
    return 1;
}

int main(int argc,char* argv[])
{
    // 信号量的id
    int sem_id;

    char op_char = 'O';

    // 创建或者打开一个信号量(信号量不存在就创建、存在就打开)
    sem_id = semget((key_t)1234,1,0666|IPC_CREAT);

    // 用一个额外的参数去控制哪个进程对信号量进行初始化,即如果当前进程有额外的参数
    // 那么它就对信号量进行初始化
    if(argc > 1)
    {
        // 初始化信号量
        if(set_semvalue(sem_id) == 0)
        {
            return -1;
        }

        op_char = 'X';
        sleep(2);
    }

    for(int i = 0; i < 10; ++i)
    {
        // 等待信号量
        if(semaphore_p(sem_id) == 0)
        {
            return -1;
        }

        // 打印一些信息
        cout << op_char ;
        cout.flush();
        sleep(2);
        cout << op_char;
        cout.flush();

        // 释放信号量,即V操作
        if(semaphore_v(sem_id) == 0)
        {
            return -1;
        }

        sleep(2);
    }

    // 执行结束,打印一些信息
    cout << endl << getpid() << " - finished" << endl;

    // 用额外的参数去控制进程去删除信号量
    if(argc > 1)
    {
        if(del_semvalue(sem_id) == 0)
        {
            return -1;
        }
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值