信号量集

信号量的最主要的目的是被用来进行同步互斥的。

同步和互斥这两个概念在我进程间通信的时候解释过,记不起来的小伙伴可以点这里

在这里,解释一下信号量为什么能达到互斥的效果,以及信号量的本质。

信号量本质上来说,就是一个计数器,其本身除了标志资源是否存在没有其他意义。

为什么这么讲呢?

举个栗子:你有100亿人民币,想象一下就是这么膨胀!那么正常人都不会把这100亿的钞票带在身上吧,我们的正常路数就是放在银行,然后美滋滋的刷卡。然后看着自己的银行卡余额,快乐生活。这个时候,你的银行卡余额就相当于是信号量,他只是一个标识数字,但是钱并不在你身上,只是在你需要消费的时候,银行的资金足以支持你的消费。但是假如有一天,你存钱的这家银行把你的钱投在别的地方亏空了,而你这个时候又刚好需要 一笔大额支出,那就有可能发生银行拿不出钱来给你的消费的情况。当然,这种情况是极少发生的。

操作系统会替我们保证信号量存在,资源也存在,其作用与银行类似。

在我们的计算机世界中,临界资源这一部分有时候是我们自己定义的,因为我们要保证某些操作的原子性

原子性:保证某个操作是一个整体,要么全部做完,要么根本不做,不会出现第三种状态。

同理,我们用信号量保证我们访问临界资源的操作是原子操作,而操作系统会为我们保证信号量的变动也是原子操作。这就是为什么信号量能够达到互斥的效果。

对信号量的操作被称为P、V操作,这是荷兰科学家迪杰斯特拉提出的,在荷兰语里,P是申请资源,V是释放资源的意思。

所以执行P操作,信号量的值会减少,执行V操作,信号量的值会增加。

信号量集函数:

semget函数:用来创建和访问一个信号量集。

int semget(key_t key,int nsems, int semflg);
//key是信号量集的名字
//nsems信号量集的个数
//semflg权限标志
//返回值:成功返回一个整数,失败返回-1

semctl函数:用于控制信号量集

int semctl(int semid, int semnum, int cmd,...);
//semid由semget返回
//semnum信号量集中信号量的序号
//cmd采取的动作
//返回值:成功0,失败-1

semop函数:用来创建和访问一个信号量集

int semop(int semid, struct sembuf* sop, unsigned nsops);
//sop指向结构数值的指针
//nsops信号量的个数
//返回值:成功0,失败-1

来段代码实例:这段代码功能是使得不同在屏幕上连续输出两个a或者两个b,如果是单个进程做到这一点显然不难,不同进程就必须要加上PV操作了!

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

int id;

void p()
{
    struct sembuf sem[1] = {0, -1, 0};
    semop(id, sem, 1);
}

void v()
{
    struct sembuf sem[1] = {0, 1, 0};
    semop(id, sem, 1);
}

void print(char c)
{
    int i = 0;
    for(; i<10; ++i)
    {
        p();
        printf("%c",c);
        fflush(stdout);
        sleep(rand()%3);
        printf("%c",c);
        fflush(stdout);
        v();
        sleep(rand()%3);
    }
}

union semnu{ int val; };

int main()
{
    srand(getpid());
    id = semget(219, 1, IPC_CREAT|0600);
    if( id == -1) perror("semget"),exit(1);

    union semnu sem;
    sem.val = 1;
    semctl(id, 0, SETVAL, sem);
    pid_t pid = fork();

    if(pid == 0){
        print('a');
    }else{
        print('b');
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zym1348010959/article/details/80720047