多线程信号量

        信号量的数据类型为结构sem_t,它本质上是一个长整型的数。函数sem_init()用来初始化一个信号量。它的原型为:函数

extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));  post

sem为指向信号量结构的一个指针;测试

pshared不为0时此信号量在进程间共享,不然只能为当前进程的全部线程共享;线程

value给出了信号量的初始值。  指针

 

函数sem_post( sem_t *sem )用来增长信号量的值。对象

当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制一样是由线程的调度策略决定的。  进程

函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,代表公共资源经使用后减小。函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。 资源

 

函数sem_destroy(sem_t *sem)用来释放信号量sem。 原型

信号量用sem_init函数建立的,下面是它的说明:
#include <semaphore.h>
int sem_init (sem_t *sem, int pshared, unsigned int value);it

    这个函数的做用是对由sem指定的信号量进行初始化,设置好它的共享选项,并指定一个整数类型的初始值。pshared参数控制着信号量的类型。若是 pshared的值是0,就表示它是当前里程的局部信号量;不然,其它进程就可以共享这个信号量。咱们如今只对不让进程共享的信号量感兴趣。(这个参数受版本影响),pshared传递一个非零将会使函数调用失败。

这两个函数控制着信号量的值,它们的定义以下所示:  
#include <semaphore.h>
int sem_wait(sem_t * sem);
int sem_post(sem_t * sem);
这两个函数都要用一个由sem_init调用初始化的信号量对象的指针作参数。
    sem_post函数的做用是给信号量的值加上一个“1”,它是一个“原子操做”---即同时对同一个信号量作加“1”操做的两个线程是不会冲突的;而同 时对同一个文件进行读、加和写操做的两个程序就有可能会引发冲突。信号量的值永远会正确地加一个“2”--由于有两个线程试图改变它。
    sem_wait函数也是一个原子操做,它的做用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始作减法。也就是说,若是你对 一个值为2的信号量调用sem_wait(),线程将会继续执行,介信号量的值将减到1。若是对一个值为0的信号量调用sem_wait(),这个函数就 会地等待直到有其它线程增长了这个值使它再也不是0为止。若是有两个线程都在sem_wait()中等待同一个信号量变成非零值,那么当它被第三个线程增长 一个“1”时,等待线程中只有一个可以对信号量作减法并继续执行,另外一个还将处于等待状态。
信号量这种“只用一个函数就能原子化地测试和设置”的能力下正是它的价值所在。还有另一个信号量函数sem_trywait,它是sem_wait的非阻塞搭档。

    最后一个信号量函数是sem_destroy。这个函数的做用是在咱们用完信号量对它进行清理。下面的定义:
#include <semaphore.h>
int sem_destroy (sem_t *sem);
这个函数也使用一个信号量指针作参数,归还本身打败的一切资源。在清理信号量的时候若是还有线程在等待它,用户就会收到一个错误。
与其它的函数同样,这些函数在成功时都返回“0”。

 

#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>

sem_t bin_sem;

void *sem1(void *arg)
{
    printf("----[%s, %d]----\n", __func__, __LINE__);
    sem_wait(&bin_sem);
    printf("pthread1------>run\n");
    return NULL;
}

void *sem2(void * arg)
{
    printf("----[%s, %d]----\n", __func__, __LINE__);
    sleep(3);
    sem_post(&bin_sem);
    printf("pthread2------>run\n");
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_t tid1, tid2;

    sem_init(&bin_sem, 0, 0);
    if (pthread_create(&tid1, 0, sem1, NULL) < 0)
    {
        printf("creat ptherad1 error!\n");
        return -1;
    }
    sleep(5);
    if (pthread_create(&tid2, 0, sem2, NULL) < 0)
    {
        printf("creat ptherad2 error!\n");
        return -1;
    }
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    return 0;
}

 

----[sem1, 9]---- ----[sem2, 17]---- pthread1------>run pthread2------>run

相关文章
相关标签/搜索