Linux IPC 同步(四):信号量

Posix  semaphore

有名信号量

/* sem_open - initialize and open a named semaphore */
#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);

/* sem_wait, sem_timedwait, sem_trywait - lock a semaphore */
#include <semaphore.h>
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

/* sem_post - unlock a semaphore */
#include <semaphore.h>
int sem_post(sem_t *sem);

/* sem_close - close a named semaphore */
#include <semaphore.h>
int sem_close(sem_t *sem);

/* sem_unlink - remove a named semaphore */
#include <semaphore.h>
int sem_unlink(const char *name);

Link with -pthread.

 

基于内存的信号量

/* sem_init - initialize an unnamed semaphore */
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);

/* sem_destroy - destroy an unnamed semaphore */
#include <semaphore.h>
int sem_destroy(sem_t *sem);

sem_init() initializes the unnamed semaphore at the address pointed to by sem. The value argument specifies the initial value for the semaphore.

The pshared argument indicates whether this semaphore is to be shared between the threads of a process, or between processes.

If pshared has the value 0, then the semaphore is shared between the threads of a process, and should be located at some address that is visible

to all threads (e.g., a global variable, or a variable allocated dynamically on the heap).

如果某个基于内存的信号量是在不同进程间共享的(sem_init的pshared参数为1),那么该信号量必须存放在共享内存中。

Posix共享内存和System V共享内存都是随内核持续的,因此只要共享内存存在,共享内存上的信号量也存在着。

 

 

信号量, 互斥锁和条件变量三者之间的差异:

(1) 信号量还有一个互斥锁没有提供的特性:互斥锁必须总是由锁住它的线程解锁,信号量的post动作却不必由执行它的wait操作的同一线程执行.

(2) 互斥锁要么被锁住, 要么被解开(类似二值信号量)

(3) 信号量有一个与之关联的状态, 信号量的post动作总是被记住.(每post一次,信号量的值都会加1)

      而向一个条件变量发送信号时, 如果没有线程等待在该条件变量上, 那么发出的信号将会丢失.

 

POSIX信号量的限制

SEM_NSEMS_MAX  一个进程可以同时打开着的最大信号量数目

SEM_VALUE_MAX  一个信号量的最大值

System V信号量

System V 创建和操作都是信号量集合

/* semget - get a System V semaphore set identifier */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);

/* semop, semtimedop - System V semaphore operations */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, unsigned nsops);
int semtimedop(int semid, struct sembuf *sops, unsigned nsops, struct timespec *timeout);

/* semctl - System V semaphore control operations */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);

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 */
};

/* The ipc_perm structure is defined as follows (the highlighted fields are settable using IPC_SET): */
struct ipc_perm {
     key_t          __key; /* Key supplied to semget(2) */
     uid_t          uid;   /* Effective UID of owner */
     gid_t          gid;   /* Effective GID of owner */
     uid_t          cuid;  /* Effective UID of creator */
     gid_t          cgid;  /* Effective GID of creator */
     unsigned short mode;  /* Permissions */
     unsigned short __seq; /* Sequence number */
};

注: 1. semget如果只是访问一个信号量集合,那么nsems参数指定为0。一旦创建好了一个信号量集合,其中的信号量数目不可改变。

        2. semget的flag参数可以是SEM_R(R代表Read),SEM_A(A代表Alter),也可以按位或上 IPC_CREAT、IPC_EXCL

        3. semop中的struct sembuf 

             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;           /* ID of process that did last op */

             semop() performs operations on selected semaphores in the set indicated by semid. Each of the nsops elements in the array pointed to by sops
             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 */

 System V 信号量的限制

 

posted @ 2015-07-07 11:38  xiaokuang  阅读(353)  评论(0编辑  收藏  举报