Linux信号量编程

343 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Linux信号量编程

信号量编程的一个小应用

代码如下:

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

union semun{
        int val;
        struct semid_ds *buf;
        unsigned short *array;
        struct seminfo *__buf;
};
void pGetKey(int id)
{
        struct sembuf set;
        set.sem_num = 0;//
        set.sem_op = -1;
        set.sem_flg = SEM_UNDO;
        semop(id,&set,1);
        printf("getKEY\n");
}

void vPutBack(int id)
{
        struct sembuf set;
        set.sem_num = 0;
        set.sem_op = 1;
        set.sem_flg = SEM_UNDO;
        semop(id,&set,1);
        printf("Put back Key\n");


}
int main(int argc,char **argv)
{
        key_t key;
        int semid;
        key = ftok(".",2);
        semid = semget(key,1,IPC_CREAT|0666);//获取/创建信号量
        union semun initsem;
        initsem.val = 0;//锁
        semctl(semid,0,SETVAL,initsem);//初始化信号量
        int pid = fork();
        if(pid > 0){
                //去拿锁
                pGetKey(semid);//拿钥匙
                printf("This is father\n");
                vPutBack(semid);//放钥匙
                semctl(semid,0,IPC_RMID);
        }else if(pid == 0){

                printf("This is child\n");
                vPutBack(semid);
        }else{
                printf("create error\n");

        }


        return 0;
}

通过上边的代码运行后,就能确保子进程比父进程先运行,通过信号量来控制。

函数原型:

NAME
semop, semtimedop - System V semaphore operations

SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

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

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

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

   semtimedop(): _GNU_SOURCE

DESCRIPTION
Each semaphore in a System V semaphore set has the following associated values:

       unsigned short  semval;   /* semaphore value */
       unsigned short  semzcnt;  /* # waiting for zero */
       unsigned short  semncnt;  /* # waiting for increase */
       pid_t           sempid;   /* PID of process that last

   semop()  performs  operations on selected semaphores in the set indicated by semid.  Each of the nsops elements in the array pointed to by sops is a structure  that  specifies  an operation  to  be performed on a single semaphore.  The elements of this structure are of type struct sembuf, containing the following members:

       unsigned short sem_num;  /* semaphore number */
       short          sem_op;   /* semaphore operation */
       short          sem_flg;  /* operation flags */

   Flags recognized in sem_flg are IPC_NOWAIT  and  SEM_UNDO.   If  an  operation  specifies  SEM_UNDO, it will be automatically undone when the process terminates.

NAME
semctl - System V semaphore control operations

SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

   int semctl(int semid, int semnum, int cmd, ...);

DESCRIPTION
semctl() performs the control operation specified by cmd on the System V semaphore set identified by semid, or on the semnum-th semaphore of that set. (The semaphores in a set are numbered starting at 0.)

   This  function  has  three or four arguments, depending on cmd.  When there are four, the
   fourth has the type union semun.  The calling program must define this union as follows:

       union semun {
           int              val;    /* Value for SETVAL */
           struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
           unsigned short  *array;  /* Array for GETALL, SETALL */
           struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                       (Linux-specific) */
       };

   The semid_ds data structure is defined in <sys/sem.h> as follows:

       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 long   sem_nsems; /* No. of semaphores in set */
       };

运行结果:
在这里插入图片描述