Linux信号量(2)-POSIX 信号量( 三 )

有名信号量有时候也叫命名信号量 , 之所以称为命名信号量 , 是因为它有一个名字、一个用户ID、一个组ID和权限 。 这些是提供给不共享内存的那些进程使用命名信号量的接口 。 命名信号量的名字是一个遵守路径名构造规则的字符串 。
接口函数sem_open函数
该函数用于创建或打开一个命名信号量 , 其原型如下:
sem_t *sem_open(const char *name, int oflag);sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value);参数

  • name是一个标识信号量的字符串 。
  • oflag用来确定是创建信号量还是连接已有的信号量 。 oflag的参数可以为0 , O_CREAT或O_EXCL:如果为0 , 表示打开一个已存在的信号量;如果为O_CREAT , 表示如果信号量不存在就创建一个信号量 , 如果存在则打开被返回 , 此时mode和value都需要指定;如果为O_CREAT|O_EXCL , 表示如果信号量存在则返回错误 。
  • mode用于创建信号量时指定信号量的权限位 , 和open函数一样 , 包括:S_IRUSR、S_IWUSR、S_IRGRP、S_IWGRP、S_IROTH、S_IWOTH 。
  • value表示创建信号量时 , 信号量的初始值 。
sem_close函数
该函数用于关闭命名信号量:
int sem_close(sem_t *);功能:单个程序可以用sem_close函数关闭命名信号量 , 但是这样做并不能将信号量从系统中删除 , 因为命名信号量在单个程序执行之外是具有持久性的 。 当进程调用_exit、exit、exec或从main返回时 , 进程打开的命名信号量同样会被关闭 。
sem_unlink函数功能:sem_unlink函数用于在所有进程关闭了命名信号量之后 , 将信号量从系统中删除:
int sem_unlink(const char *name);信号量操作函数与无名信号量一样 。
使用实例#include #include #include #include #include #include #include #include #include #define SEM_NAME " /sem_name"sem_t *p_sem;void *testThread(void *ptr){sem_wait(p_sem);sleep(2);pthread_exit(NULL);}int main(void){int i = 0;pthread_t pid;int sem_val = 0;p_sem = sem_open(SEM_NAME, O_CREAT, 0555, 5);if(p_sem == NULL){printf("sem_open %s failed!\n", SEM_NAME);sem_unlink(SEM_NAME);return -1;}for(i = 0; i < 7; i++){pthread_create(sleep(1);// pthread_join(pid, NULL);// not needed, or loopsem_getvalue(p_sem,printf("semaphore value : %d\n", sem_val);}sem_close(p_sem);sem_unlink(SEM_NAME);return 0;}命名和无名信号量的持续性命名信号量是随内核持续的 。 当命名信号量创建后 , 即使当前没有进程打开某个信号量 , 它的值依然保持 , 直到内核重新自举或调用sem_unlink()删除该信号量 。
无名信号量的持续性要根据信号量在内存中的位置确定:
如果无名信号量是在单个进程内部的数据空间中 , 即信号量只能在进程内部的各个线程间共享 , 那么信号量是随进程的持续性 , 当进程终止时他也就消失了;
如果无名信号量位于不同进程的共享内存区 , 因此只要该共享内存区仍然存在 , 该信号量就会一直存在;所以此时无名信号量是随内核的持续性 。
信号量-互斥量-条件变量很多时候信号量、互斥量和条件变量都可以在某种应用中使用 , 那这三者的差异有哪些呢?下面列出了这三者之间的差异: