信号量线程控制

(1)信号量说明
在第8 章中已经讲到,信号量也就是操作系统中所用到的PV 原语,它广泛用于进程或
线程间的同步与互斥。信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的
访问。这里先来简单复习一下PV原语的工作原理。
PV原语是对整数计数器信号量sem的操作。一次P操作使sem减一,而一次V操作使
sem 加一。进程(或线程)根据信号量的值来判断是否对公共资源具有访问权限。当信号量
sem 的值大于等于零时,该进程(或线程)具有公共资源的访问权限;相反,当信号量sem
的值小于零时,该进程(或线程)就将阻塞直到信号量sem的值大于等于0 为止。
PV 原语主要用于进程或线程间的同步和互斥这两种典型情况。若用于互斥,几个进程
(或线程)往往只设置一个信号量sem,它们的操作流程如图9.2 所示。
当信号量用于同步操作时,往往会设置多个信号量,并安排不同的初始值来实现它们之
间的顺序执行
(2)函数说明
Linux 实现了POSIX 的无名信号量,主要用于线程间的互斥同步。这里主要介绍几个常
见函数。
· sem_init用于创建一个信号量,并能初始化它的值。
· sem_wait和sem_trywait相当于P操作,它们都能将信号量的值减一,两者的区别在
于若信号量小于零时,sem_wait将会阻塞进程,而sem_trywait则会立即返回。
· sem_post相当于V操作,它将信号量的值加一同时发出信号唤醒等待的进程。
· sem_getvalue用于得到信号量的值。
· sem_destroy用于删除信号量。
(3)函数格式
所需头文件#include
函数原型int sem_init(sem_t *sem,int pshared,unsigned int value)
函数传入值
sem:信号量
pshared:决定信号量能否在几个进程间共享。由于目前Linux还没有实现进程间共享信
号量,所以这个值只能够取0
value:信号量初始化值
函数返回值
       成功:0
       出错:-1
sem_wait等函数的语法要点
所需头文件#include
函数原型
int sem_wait(sem_t *sem)
int sem_trywait(sem_t *sem)
int sem_post(sem_t *sem)
int sem_getvalue(sem_t *sem)
int sem_destroy(sem_t *sem)
函数传入值sem:信号量
函数返回值
    成功:0
    出错:-1



/* thread_sem.c */


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


#define THREAD_NUMBER 3
#define REPEAT_NUMBER 3
#define DELAY_TIME_LEVELS 10.0


sem_t sem[THREAD_NUMBER];


void * thrd_func(void *arg)
{
int thrd_num = (int)arg;
int delay_time = 0;
int count = 0;

sem_wait(&sem[thrd_num]);

printf("Thread %d is starting\n", thrd_num);

for (count = 0; count < REPEAT_NUMBER; count++)
{

delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
sleep(delay_time);
printf("\tThread %d: job %d delay = %d\n", thrd_num, count, delay_time);
}


printf("Thread %d finished\n", thrd_num);

pthread_exit(NULL);
}


int main(void)
{
pthread_t thread[THREAD_NUMBER];
int no = 0, res;
void * thrd_ret;

srand(time(NULL));

for (no = 0; no < THREAD_NUMBER; no++)
{
sem_init(&sem[no], 0, 0);
res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);
if (res != 0)
{
printf("Create thread %d failed\n", no);
exit(res);
}
}

printf("Create treads success\n Waiting for threads to finish...\n");
sem_post(&sem[THREAD_NUMBER - 1]);
for (no = THREAD_NUMBER - 1; no >= 0; no--)
{
res = pthread_join(thread[no], &thrd_ret);
if (!res)
{
printf("Thread %d joined\n", no);
}
else
{
printf("Thread %d join failed\n", no);
}
sem_post(&sem[(no + THREAD_NUMBER - 1) % THREAD_NUMBER]);

}

for (no = 0; no < THREAD_NUMBER; no++)
{
sem_destroy(&sem[no]);
}


return 0;        
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值