线程之间的信号量 Semaphore

来源:互联网 发布:程序员找女友眼光高 编辑:程序博客网 时间:2024/04/29 06:37
同一个进程中不同线程之间的同步可以使用 POSIX Semaphores(其定义在semaphore.h),这个信号量要比进程间通信使用的信号量的结构简单,注意两者是不同的事物。

创建信号量对象:sem_t sem_name;
很简单的一个变量,其中的sem_t类型也非常简单,下面是其类型定义:
typedef volatile unsigned char atomic_t
typedef atomic_t sem_t

初始化信号量:
int sem_init(sem_t *sem, int pshared, unsigned int value);
参数一:是指向信号量对象的指针
参数二:表明该信号量是否在父子进程之间共享(Linux目前是不支持的)
参数三:要信号量设定的初始值。

查询信号量:
int sem_getvalue(sem_t *sem, int *valp);
查询当前信号量的值,其值会以参数的形式返回到valp上。

P操作,索取信号量:
int sem_wait(sem_t *sem);
参数是:是指向信号量的指针。
若信号量的值为0,则线程阻塞。否则信号量的值-1。

V操作,释放信号量:
int sem_post(sem_t *sem);
参数:是指向信号量的指针。
信号量的值会+1,并且会唤醒某一个阻塞中的线程。

删除信号量:
int sem_destroy(sem_t *sem);
参数:是指向信号量的指针。
注意删除信号量时不应该存在阻塞在该信号量上的线程,否则无法删除。

上面说的主要是针对Linux,而在Mac OSX下,并不支持sem_init()对信号量的建立,而是用sem_open()。
http://stackoverflow.com/questions/8063613/c-macs-os-x-semaphore-h-trouble-with-sem-open-and-sem-wait

下面的测试程序(运行在Mac OSX)中,注释部分是适用于linux的。
#include <pthread.h>#include <semaphore.h>#include <stdio.h>#include <stdlib.h>#define NITER 1000000int count = 0; //两个线程共享同一个资源:countsem_t sem_for_linux;sem_t *s;void * ThreadAdd(void * a){    int i, tmp;       for(i = 0; i < NITER; i++)    {        sem_wait(s);        //sem_wait(&sem_for_linux);        //++count; //把自增的过程放大给你看        tmp = count;      /* copy the global count locally */        tmp = tmp+1;      /* increment the local copy */        count = tmp;      /* store the local value into the global count */        sem_post(s);        //sem_post(&sem_for_linux);    }        return NULL;}int main(int argc, char * argv[]){    pthread_t tid1, tid2;    sem_unlink("s");    s = sem_open("s", O_CREAT, 0, 1);;    //sem_init(&sem_for_linux, 0, 1);          // 创建两个线程    if(pthread_create(&tid1, NULL, ThreadAdd, NULL))    {        printf("\n ERROR creating thread 1");        exit(1);    }       if(pthread_create(&tid2, NULL, ThreadAdd, NULL))    {        printf("\n ERROR creating thread 2");        exit(1);    }       // 等待两个线程都结束    if(pthread_join(tid1, NULL))     /* wait for the thread 1 to finish */    {        printf("\n ERROR joining thread");        exit(1);    }       if(pthread_join(tid2, NULL))        /* wait for the thread 2 to finish */    {        printf("\n ERROR joining thread");        exit(1);    }       if (count < 2 * NITER)        printf("\n BOOM! count is [%d], should be %d\n", count, 2*NITER);    else        printf("\n OK! count is [%d]\n", count);       //sem_destroy(&sem_for_liux);    sem_destroy(s);       pthread_exit(NULL);}




0 0