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


sem_destroy
该函数用于对用完的信号量进行清理 , 其原型如下:
int sem_destroy(sem_t *sem);返回值:
成功返回0 , 失败返回-1 。
sem_getvalue函数
该函数返回当前信号量的值 , 通过restrict输出参数返回 。 如果当前信号量已经上锁(即同步对象不可用) , 那么返回值为0 , 或为负数 , 其绝对值就是等待该信号量解锁的线程数 。
int sem_getvalue(sem_t *restrict, int *restrict);使用实例
【实例1】:
#include #include #include #include #include #include #include #include sem_t sem;#define handle_error(msg)do { \perror(msg); \exit(EXIT_FAILURE); \}while (0)static void handler(int sig){write(STDOUT_FILENO, "sem_post() from handler\n", 24);if(sem_post(_exit(EXIT_FAILURE);}}int main(int argc, char *argv[]){int s;struct timespec ts;struct sigaction sa;if (argc != 3){fprintf(stderr, "Usage: %s\n", argv[0]);exit(EXIT_FAILURE);}if (sem_init(/* Establish SIGALRM handler; set alarm timer using argv[1] */sa.sa_handler = handler;sigemptyset(sa.sa_flags = 0;if (sigaction(SIGALRM,alarm(atoi(argv[1]));/* Calculate relative interval as current time plusnumber of seconds given argv[2] */if (clock_gettime(CLOCK_REALTIME,ts.tv_sec += atoi(argv[2]);printf("main() about to call sem_timedwait()\n");while ((s = sem_timedwait(/* Restart if interrupted by handler *//* Check what happened */if (s == -1){if (errno == ETIMEDOUT)printf("sem_timedwait() timed out\n");elseperror("sem_timedwait");}else{printf("sem_timedwait() succeeded\n");}exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);}【实例2】:
#include #include #include #include #include #include #include #include sem_t sem;void *func1(void *arg){sem_wait(int *running = (int *)arg;printf("thread func1 running : %d\n", *running);pthread_exit(NULL);}void *func2(void *arg){printf("thread func2 running.\n");sem_post(pthread_exit(NULL);}int main(void){int a = 3;sem_init(pthread_t thread_id[2];pthread_create(printf("main thread running.\n");sleep(10);pthread_create(printf("main thread still running.\n");pthread_join(thread_id[0], NULL);pthread_join(thread_id[1], NULL);sem_destroy(return 0;}有名信号量有时候也叫命名信号量 , 之所以称为命名信号量 , 是因为它有一个名字、一个用户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);【Linux信号量(2)-POSIX 信号量】信号量操作函数与无名信号量一样 。
使用实例#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()删除该信号量 。