线程之间的信号量 Semaphore

同一个进程中不同线程之间的同步可以使用 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()。

下面的测试程序(运行在Mac OSX)中,注释部分是适用于linux的。
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#define NITER 1000000
int count = 0; //两个线程共享同一个资源:count
sem_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);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值