IPC进程间通信(信号量)

基本概念

信号量是一个计数器,用于为多个进程提供对共享数据对象的访问。 信号量和P、V原语操作是由Dijkstra(迪杰斯特拉)所提出的。执行P操作时,将该进程状态设置为等待状态,并把 该进程的PCB插入相应的等待队列s.queue末尾;执行V操作时, 唤醒相应等待队列s.queue中等待的一个进程 改变其状态为就绪态 并将其插入就绪队列。

信号量的同步与互斥

互斥:P、V操作在同一个进程中
同步:P、V操作在不同进程中

信号量值含义

当S>0:S表示可用资源的个数;当S=0:表示无可用资源,无等待进程;当S<0:|S|表示等待队列中进程个数

信号量数据结构

struct semid_ds {
struct ipc_perm sem_perm;  /* Ownership and permissions */
time_t	     sem_otime; /* Last semop time */
time_t	     sem_ctime; /* Last change time */
unsigned short  sem_nsems; /* No. of semaphores in set */
};

信号量函数集

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
用来创建和访问一个信号量集,nsems:信号集中信号量的个数
int semctl(int semid, int semnum, int cmd, ...);


int semop(int semid, struct sembuf *sops, unsigned nsops);

sops是个指向一个结构数值的指针,nsops是信号量的个数。

struct sembuf {
short sem_num;
short sem_op;
short sem_flg;
};
sem_op是信号量一次PV操作时加减的数值,一般只会用到两个值,一个是“-1”,也就是P操作,等待信号量变得可用;另一个是“+1”,也就是我们的V操作,发出信号量已经变得可用
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/sem.h>
union semun
{
    int              val;
    struct semid_ds *buf;
    unsigned short  *array;
    struct seminfo  *__buf;
};
int sem_open(key_t key)
{
    int semid=semget(key,1,0666|IPC_CREAT);
    if(semid==-1)
    {
        printf("semget error!\n");
        exit(0);
    }
    return semid;
}
int sem_setval(int semid,int val)
{
    int ret=0;
    union semun se;
    se.val=val;
    ret=semctl(semid,0,SETVAL,se);
    return ret;
}
int sem_getval(int semid)
{
    int ret=0;
    union semun se;
    ret=semctl(semid,0,GETVAL,se);
    printf("semval is %d\n",se.val);
    return ret;
}
int sem_p(int semid)
{
    struct sembuf buf= {0,-1,0};
    int ret=semop(semid,&buf,1);
    return ret;
}
int sem_v(int semid)
{
    struct sembuf buf= {0,1,0};
    int ret=semop(semid,&buf,1);
    return ret;
}
int main(int argc,char*argv[])
{
    int semid=sem_open(0x1111);
    sem_setval(semid,1);
    sem_getval(semid);
    sem_p(semid);
    printf("hello world!\n");
    sem_v(semid);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_33506160/article/details/80514555