对信号量sem的一些总结

1、首先来说说信号量和互斥锁的区别:
信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,
别的线程再进行某些动作(大家都在semtake的时候,就阻塞在哪里)。
而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,
直到这个线程unlock,其他的线程才开始可以利用这个资源。

作用域
信号量: 进程间或线程间(linux仅线程间)
互斥锁: 线程间

上锁时
信号量: 只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value减一。
若value值不大于0,则sem_wait阻塞,直到sem_post释放后value值加一
互斥锁: 只要被锁住,其他任何线程都不可以访问被保护的资源



2、为了获得共享资源,进程需要执行以下操作:

1、测试控制该资源的信号量

2、若此信号量的值为正则进程可以使用该资源。进程将信号量的值减一,表示使用了一个资源单位。

3、若此信号量的值为0,则进程进入休眠状态,直至信号量得值大于0,进程被唤醒后,它返回至第一步。


3、函数原型:
1、int sem_init(sem_t *sem, int pshared, unsigned int value)
sem:指向信号量结构的一个指针;
pshared:不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;
但LinuxThreads仅实现线程间共享,因此所有非0值的pshared输入都将使sem_init()返回-1,且置errno为ENOSYS。
不过两者的实现并没有很大的区别,下面仅讨论线程间的共享。
value:给出了信号量的初始值。

2、int sem_destroy(sem_t * sem)
释放自己占用的一切资源,被注销的信号量sem要求已没有线程在等待该信号量了,否则返回-1,且置errno为EBUSY。
除此之外,LinuxThreads的信号量,注销函数不做其他动作。

3、int sem_post(sem_t * sem)
用来增加信号量的值。当一个线程要离开临界区时调用这个函数,给信号量加1。
如果有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,
它是一个“原子操作”,即同时对同一个信号量做加“1”操作的两个线程是不会冲突的

4、int sem_wait(sem_t * sem)
是一个原子操作,它的作用是从信号量的值减去一个“1”,
但它永远会先等待该信号量为一个非零值才开始做减法。
也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,信号量的值将减到1。
如果对一个值为0的信号量调用sem_wait(),这个函数就会等待直到有其它线程增加了这个值使它不再是0为止。
如果有两个线程都在sem_wait()中等待同一个信号量变成非零值,那么当它被第三个线程增加一个“1”时,
等待线程中只有一个能够对信号量做减法并继续执行,另一个还将处于等待状态。


5、int sem_trywait(sem_t * sem)
sem_trywait()为sem_wait()的非阻塞版,如果信号量计数大于0,则信号量立即减1并返回0,
否则立即返回-1,errno置为EAGAIN。


6、int sem_getvalue(sem_t * sem, int * sval)
读取sem中信号量计数,存于*sval中,并返回0。

你可能感兴趣的:(linux)