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 信号量的限制