文章结束给大家来个程序员笑话:[M]
这篇文章介绍下信号量,信号量的功能并不是进程间通信,是进程间同步。在线程部份已提到过信号量的概念,用到的是匿名信号量,能够实现线程间的同步。
上篇文章中
一样Linux提供给我们两种信号量:SystemV的信号量和Posix的信号量。
仍然是先来看下Posix的信号量(须要-lrt),相关函数如下:
sem_t *sem_open(const char *name, int oflag); sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); int sem_close(sem_t *sem); int sem_unlink(const char *name); int sem_wait(sem_t *sem); int sem_trywait(sem_t *sem); int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); int sem_post(sem_t *sem); int sem_getvalue(sem_t *sem, int *sval);
匿名信号量应用sem_init()函数来打开,而定名信号量应用sem_open()来打开,相关操作和共享内存是类似的。应用sem_close()关闭 sem_unlink()删除。信号量的电灯灭灯操作和匿名信号量是一样的。
SystemV的信号量其实并不是信号量而是信号量集,是多个信号量的集合(当然可以只有一个)。创建/打开信号量的函数是semget():
int semget(key_t key, int nsems, int semflg);
这个函数在应用上和msgget() shmget()是类似的,除了多一个nsems参数,表示的是信号量会合信号量的个数。
SystemV信号来那个的初始化和获得/设置值应用semctl()函数:
int semctl(int semid, int semnum, int cmd, .../* union semnum arg */);
cmd:
IPC_RMID(删除信号量) SETVAL(设置第semnum信号量的值) GETVAL(获得semnum信号量的值)SETALL(设置全部信号量的值) GETALL(获得全部信号量的值)
相关值是又公用体arg传递的,union semnum的结构:
union semun { int val; /* Value for SETVAL */ unsigned short *array; /* Array for GETALL, SETALL */ };
如果是SETVAL GETVAL应用的val,GETALL SETALL应用的array。
信号量的PV操作(点灯 灭灯),应用semop停止操作:
int semop(int semid, struct sembuf *sops, unsigned nsops);
sops是操作数组,nsops是数组的长度。struct smebuf的结构如下:
struct sembuf { unsigned short sem_num; /* semaphore number */ short sem_op; /* semaphore operation */ short sem_flg; /* operation flag */ };
sem_num是操作的第几个信号量,sem_op是执行的PV操作,如1 2 -1 -2。sem_flg是参数,包括:
IPC_NOWAIT(对信号的操作不能满足时,semop()不会阻塞,当即返回并设置errno)、
SEM_UNDO(将会自动撤消该进程终止时)。
文章结束给大家分享下程序员的一些笑话语录: 乔布斯:怎么样还是咱安全吧!黑客:你的浏览器支持国内网银吗?苹果可以玩国内的网游吗乔布斯:......不可以黑客:那我研究你的漏洞干嘛,我也需要买奶粉!
--------------------------------- 原创文章 By
进程间通信和学习
---------------------------------