进程间通信——信号量

1、信号量:特殊的变量,用来同步进程。

内核信号量类似于自旋锁,因为当锁关闭着时,它不允许内核控制路径继续进行。然而,当内核控制路径试图获取内核信号量锁保护的忙资源时,相应的进程就被挂起。只有在资源被释放时,进程才再次变为可运行。
只有可以睡眠的函数才能获取内核信号量;中断处理程序和可延迟函数都不能使用内核信号量。

原子减一(p操作,代表获取资源)

原子加一(v操作,代表释放资源)


想要了解信号量就得知道临界资源和临界区的概念

临界资源:同一时刻只允许一个进程(线程)访问的资源。

临界区:访问临界资源的代码段。

 信号量分为两种:

二值信号量:值取0和1

计数信号量:值可以大于1

2、信号量的函数

int semget(key_t key, int nsems, int semflg);创建信号量

 int semctl(int semid, int semnum, int cmd, ...);对信号量进行控制

int semop(int semid, struct sembuf *sops, unsigned nsops); 改变信号量的值(p,v操作)

int semtimedop(int semid, struct sembuf *sops, unsigned nsops,struct timespec *timeout);

 

3、具体实例

#include
#include
#include
#include"sem.h"

static int semid = -1;
void sem_init()
{
    semid = semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);
    if(semid == -1)
    {
        semid = semget((key_t)1234,1,0600);
        if(semid == -1)
        {
            perror("semget error");
        }
    }
    else
    {
        union semun a;
        a.val = 0;

        if(semctl(semid,0,SETVAL,a) == -1)
        {
            perror("semctl error");
        }
    }
}
void sem_p()
{
    struct sembuf buf;
    buf.sem_num = 0;
    buf.sem_op = -1;
    buf.sem_flg = SEM_UNDO;

    if(semop(semid,&buf,1)==-1)
    {
        perror("semop error");
    }
}
void sem_v()
{

    struct sembuf buf;
    buf.sem_num = 0;
    buf.sem_op = 1;
    buf.sem_flg = SEM_UNDO;

    if(semop(semid,&buf,1)==-1)
    {
        perror("semop error");
    }
}
void sem_destroy()
{
    if(semctl(semid,0,IPC_RMID) == -1)
    {
        perror("semctl error");
    }
}

 

你可能感兴趣的:(Linux,C语言)