信号量

1 #include <sys/sem.h>
2 // 创建或获取一个信号量组:若成功返回信号量集ID,失败返回-1
3 int semget(key_t key, int num_sems, int sem_flags);
  当semget创建新的信号量集合时,必须指定集合中信号量的个数(即num_sems),通常为1; 
  如果是引用一个现有的集合,则将num_sems指定为 0 。
4 // 对信号量组进行操作,改变信号量的值:成功返回0,失败返回-1
5 int semop(int semid, struct sembuf semoparray[], size_t numops); 
  struct sembuf 
  {
   short sem_num; // 信号量组中对应的序号,0~sem_nums-1
   short sem_op;  // 信号量值在一次操作中的改变量
   short sem_flg; // IPC_NOWAIT, SEM_UNDO
  } 
6 // 控制信号量的相关信息
7 int semctl(int semid, int sem_num, int cmd, ...);
  SETVAL:用于初始化信号量为一个已知的值
  IPC_RMID:删除一个信号量集合  
#include <iostream>                                                                                          
#include <sys/types.h>
#include <sys/sem.h>
#include <unistd.h>

// 联合体 用于semctl初始化
union semun {
    int val; //for SETVAL
    struct semid_ds *buf;
    unsigned short *array;
};
// 初始化信号量
int init_sem(int sem_id,int value)
{
    union semun tmp;
    tmp.val = value;
    if(semctl(sem_id,0,SETVAL,tmp) == -1)
    {   
        perror("Init Semaphore Error");
        return -1;
    }
    return 0;
}

// P操作
int sem_p(int sem_id)
{
    struct sembuf sbuf;
    sbuf.sem_num = 0; // 序号
    sbuf.sem_op = -1; // P操作
    sbuf.sem_flg = SEM_UNDO;

    if(semop(sem_id,&sbuf,1) == -1)
    {   
        perror("P operation Error");
        return -1;
    }
    return 0;
}
// V操作
int sem_v(int sem_id)
{
    struct sembuf sbuf;
    sbuf.sem_num = 0;
    sbuf.sem_op = 1;
    sbuf.sem_flg = SEM_UNDO;

    if(semop(sem_id,&sbuf,1) == -1)
    {
        perror("V operation Error");
        return -1;
    }
    return 0;
}
// 删除信号量集
int del_sem(int sem_id)
{
    union semun tmp;
    if(semctl(sem_id,0,IPC_RMID,tmp) == -1)
    {
        perror("Delete Semaphore Error");
        return -1;
    }
    return 0;
}

int main()
{
    int sem_id; // 信号量集ID
    key_t key;
    pid_t pid;
    // 获取key值
    if((key = ftok(".",‘z‘)) < 0)
    {
        perror("ftok error");
        exit(1);
    }
    // 创建信号量集,其中只有一个信号量
    if((sem_id = semget(key,1,IPC_CREAT|0666)) == -1)
    {
        perror("semget error");
        exit(1);
    }
    // 初始化: 初值设为0资源被占用
    init_sem(sem_id,0);

    if((pid=fork()) < 0)
    {
        perror("fork");
    }else if(pid == 0)
    {
        sleep(2);
        printf("Process child: pid=%d\n",getpid());  
        sem_v(sem_id);
        del_sem(sem_id);
        // 父进程
    }
    return 0;

信号量

上一篇:C# 发送HTTP请求超时解决办法


下一篇:三、连接本地/远程KVM