POSIX信号量机制是3中IPC机制之一,3中IPC机制源于POSIX.1的实施扩展。
POSIX信号量意在解决XSI信号量接口的及格缺陷。
● 相比于XSI接口,POSIX信号量接口考虑到了更高性能的实现。
● POSIX信号量接口使用简单:没有信号量集,在熟悉的文件系统操作后一些接口被模式化了。
● POSIX信号量在删除时表现的更加完美。删除时操作能继续正常工作直到该信号量的最后一次引用被释放。
POSIX信号量由两种形式:命名的和未命名的。它们的差异在于创建和销毁的形式上,但其他工作一样。未命名信号量只存在内存中,并要求能使用信号量的进程必须可以访问内存。命名信号量可以通过名字访问,可以被任何已知它们民资的进程中的线程使用。
调用sem_open函数来创建一个新的命名信号量或者使用一个现有的信号量。
#include <semaphore.h> sem_t *sem_open(const char *name, int oflag, … / * mode_t mode, unsigned int value * /); 返回值:若成功,返回指向信号量的指针;若出错,返回SEM_FAILED |
---|
当使用一个现有的命名信号量时,只需要指定两个参数:信号量的名字和oflag参数的0值。当这个oflag参数有O_CREAT标志集是,如果命名信号量不存在,则创建一个新的。如果它已经存在,则会被使用,但是不会有额外的初始化发生。
如果想在信号量上进行操作,sem_open函数会返回一个信号量指针,用于传递到其他函数的信号量上。当完成信号量操作时,可以调用sem_close函数来释放任何信号量相关的资源。
#include <semaphore.h> int sem_close(sem_t *sem); 返回值:若成功,返回0;若出错,返回-1 |
---|
可以使用sem_unlink函数来销毁一个命名变量。
#include <semaphore.h> int sem_unlink(const char *name); 返回值:若成功,返回0;若出错,返回-1 |
---|
sem_unlink函数删除信号量打开的名字。如果没有打开的信号量被引用,则该信号会被销毁,否则,销毁会延迟到最后一个打开的引用关闭。
可以使用sem_wait和sem_trywait函数来实现信号量的减1操作。
#include <semaphore.h> int sem_trywait(sem_t *sem); int sem_wait(sem_t *sem); 返回值:若成功,返回0;若出错,返回-1 |
---|
使用sem_wait函数时,如果信号量时0就会发生阻塞。直到成功使信号减1或者被信号中断时才会返回。可以使用sem_trywait函数来避免阻塞。调用sem_trywait时,如果信号量时0,不会发生阻塞,而是会返回-1并且将errno设置为EAGAIN。
可以选择阻塞一段确定的时间。可以使用sem_timedwait函数。
#include <semaphore.h> #include <time.h> int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict tsptr); 返回值:若成功,返回0;若出错,返回-1 |
---|
可以使用tsptr参数指定绝对时间。超时时基于CLOCK_REALTIME时钟的。若到了超时时间信号量计数没能减1,sem_timedwait将返回-1,将errno设置为ETIMEDOUT。
可以调用sem_post函数使信号量增1。
#include <semaphore.h> int sem_post(sem_t *sem); 返回值:若成功,返回0;若出错,返回-1 |
---|
在单个进程中使用POSIX信号量时,使用未命名信号量更容易。这仅仅改变销毁信号量的方式。可以调用sem_inti函数来创建一个未命名的信号量。
#include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int vlaue); 返回值:若成功,返回0;若出错,返回-1 |
---|
pshared参数表明是否在多个进程中使用信号量。value参数指定了信号量的初始值。
需要声明一个sem_t类型的变量并将其地址传给sem_init来实现初始化。
对未命名信号量的使用已经完成时,可以调用sem_destroy函数丢弃它。
#include <semaphore.h> int sem_destroy(sem_t *sem); 返回值:若成功,返回0;若出错,返回-1 |
---|
调用sem_destroy之后,不能再使用任何带有sem的信号量函数,除非调用sem_init函数重新初始化它。
调用sem_getvalue函数可用来检索信号量值。
#include <semaphore.h> int sem_getvalue(sem_t *restrict sem, int *restrict valp); 返回值:若成功,返回0;若出错,返回-1 |
---|