设为首页 加入收藏

TOP

信号量整理
2019-09-04 00:59:39 】 浏览:29
Tags:信号 整理

信号量

一、

1、信号量的数据类型为结构sem_t,它本质上是一个长整型的数。

2、例如:

typedef   struct
{
    struct   _pthread_fastlock   __sem_lock;
    int   __sem_value;
    _pthread_descr   __sem_waiting;
}   sem_t;

3、sem_t分为有名和无名。有名的sem_t通过sem_open来创建用于进程通信;而无名的sem_t通过sem_init的初始化是基于内存的信号量

4、有名和无名的sem_t主要区别:

1)效率:有名sem_t是放在文件,无名的sem_t是放在内存。

2)限制:有名的sem_t可以用来同步多线程,任意多进程。而无名的sem_t可以用来同步多线程,以及Fork出来的进程间的同步。

(如果没有放到共享内存,就算将pshared设置为1,也起不了作用。

3)pshared传递一个非零将会使函数调用失败,属于无名信号量。

二、

1、sem_init:用来初始化一个信号量。

1、int sem_init(sem_t *sem, int pshared, unsigned int value);

1)sem_init函数是Posix信号量操作中的函数,作用是对由sem指定的信号量进行初始化。sem_init() 初始化一个定位在 sem 的匿名信号量。

2)sem为指向信号量结构的一个指针,指向信号量对象。

3)value 参数指定信号量(sem)的初始值。value给出了信号量的初始值。指定信号量值的大小。一般为0或者1。

4)pshared 参数指明信号量的类型,即信号量是由进程内线程共享,还是由进程之间共享。如果 pshared 的值为 0,只能为当前进程的所有线程共享,并且应该放置在这个进程的所有线程都可见的地址上(如全局变量,或者堆上动态分配的变量)。pshared不为0时,其它进程就能够共享这个信号量。

5)sem_init()该函数调用成功返回0,失败返回-1。 

2、补充:
pshared传递一个非零将会使函数调用失败。 

2、sem_post:

1、int sem_post(sem_t *sem);用来增加信号量的值。

2、 sem_post函数的作用是给信号量的值加上一个“1”,它是一个“原子操作”即同时对同一个信号量做加“1”操作的两个线程是不会冲突的,而同时对同一个文件进行读、加和写操作的两个程序就有可能会引起冲突,信号量的值永远会正确地加一个“2”--因为有两个线程试图改变它。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。释放信号量,让信号量的值加1。相当于V操作。 

3、sem_wait:

1、int sem_wait(sem_t * sem);被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。等待信号量,如果信号量的值大于0,将信号量的值减1,立即返回。如果信号量的值为0,则线程阻塞。相当于P操作。成功返回0,失败返回-1。

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

例如:

sem_init(&svs.useFlag, 0, 1);       //初始化信号量,同一个进程中线程共享,并且赋值为1。

sem_wait(&svs.useFlag);         // 锁定svs数据,以免在创建的新线程使用前被修改,信号量减一。

sem_post(&svs.useFlag);        //信号量加1。

sem_post(&svs->useFlag);        //信号量加1。
   4、sem_trywait 

1、sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。

2、信号量这种“只用一个函数就能原子化地测试和设置”的能力下正是它的价值所在。还有另外一个信号量函数sem_trywait,它是sem_wait的非阻塞搭档。
5、sem_destroy

1、sem_destroy(sem_t *sem)用来释放信号量sem。其中sem是要销毁的信号量。只有用sem_init初始化的信号量才能用sem_destroy销毁。这个函数的作用是在我们用完信号量对它进行清理。下面的定义:
   #include<semaphore.h>
   int sem_destroy (sem_t *sem);
    这个函数也使用一个信号量指针做参数,归还自己占据的一切资源。在清理信号量的时候如果还有线程在等待它,用户就会收到一个错误。与其它的函数一样,这些函数在成功时都返回“0”。

 

信号量的使用如下步骤小结:
 1.声明信号量sem_t sem1;
 2.初始化信号量sem_init(&sem1,0,1); /
 3.sem_post和sem_wait函数配合使用来达到线程同步
 4.释放信号量int sem_destroy (sem_t *sem1);

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇初级模拟电路:3-4 共基放大电路.. 下一篇按键长短按

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目