相关函数:
sem_init 初始化信号量
sem_post 点灯/释放资源
sem_wait 等待灯亮并灭灯/占用资源
sem_trywait
sem_destroy 销毁信号量
=============================================================
信号量也叫信号灯
只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value减一。
若value值不大于0,则sem_wait使得线程阻塞。
信号量是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语;
直到sem_post释放后value值加一,但是sem_wait返回之前还是会将此value值减一。
int sem_init(sem_t *sem, int pshared, unsigned int value)
这是创建信号灯的API,其中value为信号灯的初值,pshared表示是否为多进程共享而不仅仅是用于一个进程。
LinuxThreads没有实现多进程共享信号灯,因此所有非0值的pshared输入都将使sem_init()返回-1,且置errno为ENOSYS。
初始化好的信号灯由sem变量表征,用于以下点灯、灭灯操作。
int sem_destroy(sem_t * sem)
被注销的信号灯sem要求已没有线程在等待该信号灯,否则返回-1,且置errno为EBUSY。
除此之外,LinuxThreads的信号灯 注销函数不做其他动作。
点灯和灭灯
int sem_post(sem_t * sem)
点灯操作将信号灯值原子地加1,表示增加一个可访问的资源。
int sem_wait(sem_t * sem)
int sem_trywait(sem_t * sem)
sem_wait()为等待灯亮操作,等待灯亮(信号灯值大于0),然后将信号灯原子地减1,并返回。
sem_trywait()为sem_wait()的非阻塞版,如果信号灯计数大于0,则原子地减1并返回0,否则立即返回-1,errno置为EAGAIN。
获取灯值
int sem_getvalue(sem_t * sem, int * sval)
读取sem中的灯计数,存于*sval中,并返回0。
互斥锁和信号量区别:
其实二者真正的区别是互斥锁是实现一个原子操作,也就是避免不同线程同时访问一个共享资源,导致出现异常;
而信号量则是为了线程同步所设计的。
当信号量是二进制信号量的时候,也能用来充当mutex,但是强烈建议不要这么使用。
互斥锁:多线程多任务互斥的概念;一个线程占用了某个资源,别的线程就无法访问;互斥量表现互斥现象的数据结构,也被当作二元信号灯。
信号量:多线程多任务同步的概念;B线程要等A线程完成某一任务之后,再进行自己下面的步骤;(信号灯);