#include
/* semop flags */
#define SEM_UNDO 0x1000 /* undo the operation on exit */
/* semctl Command Definitions. */
#define GETPID 11 /* get sempid */
#define GETVAL 12 /* get semval */
#define GETALL 13 /* get all semval's */
#define GETNCNT 14 /* get semncnt */
#define GETZCNT 15 /* get semzcnt */
#define SETVAL 16 /* set semval */
#define SETALL 17 /* set all semval's */
/* ipcs ctl cmds */
#define SEM_STAT 18
#define SEM_INFO 19
/* Obsolete, used only for backwards compatibility and libc5 compiles */
struct semid_ds {
struct ipc_perm sem_perm; /* permissions .. see ipc.h */
__kernel_time_t sem_otime; /* last semop time */
__kernel_time_t sem_ctime; /* last change time */
struct sem *sem_base; /* ptr to first semaphore in array */
struct sem_queue *sem_pending; /* pending operations to be processed */
struct sem_queue **sem_pending_last; /* last pending operation */
struct sem_undo *undo; /* undo requests on this array */
unsigned short sem_nsems; /* no. of semaphores in array */
};
/* Include the definition of semid64_ds */
#include
/* semop system calls takes an array of these. */ struct [color="#0000ff"]sembuf {
unsigned short sem_num; /* semaphore index in array */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
/* arg for semctl system calls. */ union [color="#0000ff"]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 */
void *__pad;
}; struct seminfo {
int semmap;
int semmni;
int semmns;
int semmnu;
int semmsl;
int semopm;
int semume;
int semusz;
int semvmx;
int semaem;
};
[color="#0000ff"]/*具体系统的限制*
[color="#0000ff"]cat /proc/sys/kernel/sem 查看[color="#0000ff"]*/
#define SEMMNI 128 /*
/* unused */
#define SEMUME SEMOPM /* max num of undo entries per process */
#define SEMMNU SEMMNS /* num of undo structures system wide */
#define SEMMAP SEMMNS /* # of entries in semaphore map */
#define SEMUSZ 20 /* sizeof struct sem_undo */
#endif /* _LINUX_SEM_H */
typedef union
{
char __size[__SIZEOF_SEM_T];
long int __align;
} sem_t;
//===============================================================================
信号灯的定义 如下 来自 man 7 SEM_OVERVIEW
A semaphore is an integer whose value is never allowed to fall below zero. Two operations can be performed on semaphores: increment the semaphore value by one (sem_post(3)); and decrement the semaphore value by one (sem_wait(3)). If the value of a semaphore is currently zero, then a sem_wait(3) operation will block until the value becomes greater than zero.
为了移植方便我们严格按照 POSIX 标准 so POSIX semaphores come in two forms: named semaphores and unnamed semaphores
目前的linux 2.6.x.x 版本是支持 有名信号灯的
named semaphore 创建
The sem_open(3) function creates a new named semaphore or opens an existing named semaphore. After the semaphore has been opened, it can be operated on using sem_post(3) and sem_wait(3). When a process has finished using the semaphore, it can use sem_close(3) to close the semaphore. When all processes have fin‐ished using the semaphore, it can be removed from the system using sem_unlink(3).
Unnamed semaphores 创建
Before being used, an unnamed semaphore must be initialized using sem_init(3). It can then be operated on using sem_post(3) and sem_wait(3). When the semaphore is no longer required, and before the memory in which it is located is deallocated, the semaphore should be destroyed using sem_destroy(3).
先说 named semaphore how to
函数原型
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int val)
[color="#990099"]#include /* For O_* constants */
[color="#660099"]#include /* For mode constants */
[color="#990099"]#include
main() {
sem_t * my_semaphore;
int rc;
my_semaphore = sem_open("myfile", //
O_CREAT, S_IRUSR | S_IWUSR, 10);
if(my_semaphore==SEM_FAILED){
perror(" Name semaphore failure ");
}
sleep(15); // for debug
if( sem_unlink("myfile")!=0)
perror("delete Name semaphore failure !\n");
}
[email=v@debian-NanJing:%7E/C/Clib/Semaphores$]@debian-NanJing:~/C/Clib/Semaphores$[/email]
./a.out &
[1] 4573
[email=v@debian-NanJing:%7E/C/Clib/Semaphores$]@debian-NanJing:~/C/Clib/Semaphores$[/email]
ls -i /dev/shm/
16156 sem.myfile
[email=v@debian-NanJing:%7E/C/Clib/Semaphores$]@debian-NanJing:~/C/Clib/Semaphores$[/email]
ls -il /dev/shm/
total 4
16156 -rw------- 1 vivi vivi 16 2009-12-12 23:48 sem.myfile
[email=v@debian-NanJing:%7E/C/Clib/Semaphores$]@debian-NanJing:~/C/Clib/Semaphores$[/email]
如果你一定要写成那样的话需要自己建一级目录 其余的参数同 open 不多说了 。
匿名信号集的创建比较简单了
函数定义
int sem_init(sem_t *sem, int pshared, unsigned int value);
int semget(key_t key, int nsems, int semflg); 创建方式类似于消息队列
这2个函数都可以创建信号集 semget 需要做KEY 并且需要初始化通过
int semctl(int semid, int semnum, int cmd, ...);
sem_init 比较麻烦 需要分2种情况区别对待
The pshared argument indicates whether this semaphore is to be shared between the [color="#0000ff"]threads of a process, or [color="#66cccc"]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).
If pshared is non-zero, then the semaphore is shared between processes, and should be located in a region of shared memory (see shm_open(3), mmap(2), and shmget(2)). (Since a child created by fork(2) inherits its parent’s
memory mappings, it can also access the semaphore.) Any process that can access the shared memory region can operate on the semaphore using sem_post(3), sem_wait(3), etc.