linux下信号量的使用

8 篇文章 0 订阅

信号量是为了防止在多个程序同时访问一个共享资源发生问题的情况下引入的。

在两个进程中对信号量控制的伪代码都是下面这样的

semaphore sv = 1;


loop forever{

p(sv);

critical code section;

v(sv);

noncritical code section;

}




下面来学习一个信号量使用的例子,在任何时候都只有一个进程可以进入临界区域

具体代码如下:

#include <iostream>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/sem.h>
using namespace std;

union semun{
    int value;
    struct semid_ds *buf;
    unsigned short* array;

};

//定义的接口  和初始的信号量ID
static int set_semvalue(void);
static void del_semvalue(void);
static int semaphore_p(void);
static int semaphore_v(void);
static int sem_id;

int main(int argc , char* argv[])
{

    int i;
    int pause_time;
    char op_char = '0';

    srand((unsigned int)getpid());

    sem_id = semget((key_t)1234  , 1 , 0666| IPC_CREAT);

    if(argc > 1){
        if(!set_semvalue()){
            fprintf(stderr , "Failed to initialized semaphored!\n");
            exit(EXIT_FAILURE);
        }


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

    //接下来是一个循环,进入和离开临界区10次。在每次循环的开始,首先调用semphore_p,它在程序进入临界区的时候设置信号量等级进入、
    for(int i =  0 ; i < 10 ; i++){
        if(!semaphore_p()) exit(EXIT_FAILURE);
        printf("%c" , op_char);
        fflush(stdout);
        pause_time = rand() % 3;
        sleep(pause_time);
        printf("%c" , op_char); fflush(stdout);

        //在临界区域后,调用semaphore_v将信号量设置为可用。然后等待一段随机的时间,再进下一次循环。在整个循环完成后,调用del_semaphore来清理代码
        if(!semaphore_v())exit(EXIT_FAILURE);

        pause_time = rand() % 2;
        sleep(pause_time);

    }


    printf("\n %d - finished\n" , getpid());

    if(argc > 1){
        sleep(10);
        del_semvalue();
    }

    exit(EXIT_SUCCESS);

    //return 0;
}


static int set_semvalue(void){
//函数通过将semctl调用的commang参数设置为SETVAL来初始化信号量。在使用前必须要这样做
    union semun sem_union;
    sem_union.value = 1;
    if(semctl(sem_id ,0, SETVAL , sem_union) == -1) return (0);
    return (1);

}
static void del_semvalue(void){
//删除信号量ID

union semun sem_union;
if(semctl(sem_id ,0, IPC_RMID , sem_union) == -1)
    fprintf(stderr , "Failed to delete semaphore\n");
}
static int semaphore_p(void){
//对信号量做减1的操作


struct sembuf sem_b;

sem_b.sem_num = 0;
sem_b.sem_op= -1;
sem_b.sem_flg = SEM_UNDO;

if(semop(sem_id , &sem_b , 1) == -1){
    fprintf(stderr , "semaphore_p failed\n");
    return (0);
}

return (1);

}
static int semaphore_v(void){
    struct sembuf sem_b;

    sem_b.sem_num = 0;
    sem_b.sem_op = 1;
    sem_b.sem_flg = SEM_UNDO;
    if(semop(sem_id , &sem_b , 1) == -1){
        fprintf(stderr , "semaphore_v failed\n");
        return(0);
    }

    return (1);

}




在运行的时候,在命令行中 首先将第一个进程挂起,然后打开第二个进程就可以啦。

./test1 1 &

./test1 


这样就可以看到两个进程一直在交替访问共享的内存啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值