POSIX信号量机制是3种IPC机制之一,3种IPC机制源于POSIX.1的实时扩展。
创建一个新的命名信号量或者使用一个现有信号量
#include <fcntl.h> #include <sys/stat.h> #include <semaphore.h> sem_t *sem_open(const char *name, int oflag); sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); Link with -pthread 返回值:成功指向信号量的指针,出错SEM_FAILED name:信号灯外部名字 oflag:选择创建或打开一个现有的信号灯 mode:权限位 value:信号灯初始值
当完成信号量操作时,可以调用sem_close函数来释放任何信号量相关的资源
#include <semaphore.h> int sem_close(sem_t *sem); 返回值:成功0,出错-1 Link with -pthread sem:指向信号量的指针
可以使用sem_unlink函数来销毁一个命名信号量
#include <semaphore.h> int sem_unlink(const char *name); 返回值:成功0,出错-1 Link with -pthread name:信号灯的外部名字
实现信号量的减1操作
#incldue <semaphore.h> int sem_wait(sem_t *sem); int sem_trywait(sem_t *sem); 返回值:成功0,出错-1 sem:指向信号灯的指针
还有一个阻塞一段确定的时间来减1操作
#include <semaphore.h> #include <time.h> int sem_timedwait(sem_t *restrict sem, const struct timespec *abs_timeout); 返回值:成功0,出错-1 Link with -pthread sem:指向信号灯的指针 abs_timeout:绝对时间。超时基于CLOCK_REALTIME时钟的
使信号量值增1
#include <semaphore.h> int sem_post(sem_t *sem); 返回值:成功0,出错-1 Link with -pthread sem:指向信号灯的指针
创建一个未命名的信号量
#incldue <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int value); 返回值:成功0,出错-1 sem:指向信号灯的指针 pshared:表明是否在多个进程中使用信号量,如果是,设置成一个非0值 value:信号量的初始值
对未命名信号量的使用已经完成时,可以丢弃它
#include <semaphore.h> int sem_destroy(sem_t *sem); 返回值:成功0,出错-1 sem:指向信号灯的指针
可以用来检索信号量值
#include <semaphore.h> int sem_getvalue(sem_t *sem, int *sval); 返回值:成功0,出错-1 sem:指向信号灯的指针 sval:指向的整数值将包含信号量值。除非使用额外的同步机制来避免这种竞争,否则sem_getvalue函数只能用于调试
例程1:
建立两个线程,这两个线程各自将自己的一个整型变量i从1递增到100,并通过信号量控制递增的过程,即这两个整型变量的差不能超过5。
1 lude <stdio.h> 2 #include <semaphore.h> 3 #include <pthread.h> 4 5 #define MAX 100 6 sem_t sem1, sem2; 7 8 void *th_fn1(void *arg) 9 { 10 int i; 11 for(i=0;i<MAX;i++) 12 { 13 sem_wait(&sem1); 14 printf("number in thread1 is %d ", i); 15 sem_post(&sem2); 16 } 17 pthread_exit((void *)"thread1 exit "); 18 } 19 20 void *th_fn2(void *arg) 21 { 22 int i; 23 for(i=0;i<MAX;i++) 24 { 25 sem_wait(&sem2); 26 printf("number in thread2 is %d ", i); 27 sem_post(&sem1); 28 } 29 pthread_exit((void *)"thread2 exit "); 30 } 31 32 int main(int argc, char *argv[]) 33 { 34 pthread_t tid1, tid2; 35 void *tret; 36 if(sem_init(&sem1, 0, 5) == -1) 37 { 38 perror("sem1 init failed "); 39 return -1; 40 } 41 if(sem_init(&sem2, 0, 5) == -1) 42 { 43 perror("sem2 init failed "); 44 return -1; 45 } 46 47 pthread_create(&tid1, NULL, th_fn1, NULL); 48 pthread_create(&tid2, NULL, th_fn2, NULL); 49 50 pthread_join(tid1, &tret); 51 pthread_join(tid2, &tret); 52 53 sem_destroy(&sem1); 54 sem_destroy(&sem2); 55 56 return 0; 57 }