linux下的多线程开发,Linux下的多线程编程

函数pthread_cond_broadcast(pthread_cond_t *cond)用来唤醒所有被阻塞在条件变量cond上的线程。这些线程被唤醒后将再次竞争相应的互斥锁,所以必须小心使用这个函数。

4.4 信号量

信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。当公共资源增加时,调用函数sem_post()增加信号量。只有当信号量值大于0时,才能使用公共资源,使用后,函数sem_wait()减少信号量。函数sem_trywait()和函数pthread_ mutex_trylock()起同样的作用,它是函数sem_wait()的非阻塞版本。下面我们逐个介绍和信号量有关的一些函数,它们都在头文件 /usr/include/semaphore.h中定义。

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

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

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。

下面我们来看一个使用信号量的例子。在这个例子中,一共有4个线程,其中两个线程负责从文件读取数据到公共的缓冲区,另两个线程从缓冲区读取数据作不同的处理(加和乘运算)。

/* File sem.c */

#include

#include

#include

#define MAXSTACK 100

int stack[MAXSTACK][2];

int size=0;

sem_t sem;

/* 从文件1.dat读取数据,每读一次,信号量加一*/

void ReadData1(void){

FILE *fp=fopen("1.dat","r");

while(!feof(fp)){

fscanf(fp,"%d %d",&stack[size][0],&stack[size][1]);

sem_post(&sem);

++size;

}

fclose(fp);

}

/*从文件2.dat读取数据*/

void ReadData2(void){

FILE *fp=fopen("2.dat","r");

while(!feof(fp)){

fscanf(fp,"%d %d",&stack[size][0],&stack[size][1]);

sem_post(&sem);

++size;

}

fclose(fp);

}

/*阻塞等待缓冲区有数据,读取数据后,释放空间,继续等待*/

void HandleData1(void){

while(1){

sem_wait(&sem);

printf("Plus:%d+%d=%dn",stack[size][0],stack[size][1],

stack[size][0]+stack[size][1]);

--size;

}

}

void HandleData2(void){

while(1){

sem_wait(&sem);

printf("Multiply:%d*%d=%dn",stack[size][0],stack[size][1],

stack[size][0]*stack[size][1]);

--size;

}

}

int main(void){

pthread_t t1,t2,t3,t4;

sem_init(&sem,0,0);

pthread_create(&t1,NULL,(void *)HandleData1,NULL);

pthread_create(&t2,NULL,(void *)HandleData2,NULL);

pthread_create(&t3,NULL,(void *)ReadData1,NULL);

pthread_create(&t4,NULL,(void *)ReadData2,NULL);

/* 防止程序过早退出,让它在此无限期等待*/

pthread_join(t1,NULL);

}

在Linux下,我们用命令gcc -lpthread sem.c -o sem生成可执行文件sem。 我们事先编辑好数据文件1.dat和2.dat,假设它们的内容分别为1 2 3 4 5 6 7 8 9 10和 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 ,我们运行sem,得到如下的结果:

Multiply:-1*-2=2

Plus:-1+-2=-3

Multiply:9*10=90

Plus:-9+-10=-19

Multiply:-7*-8=56

Plus:-5+-6=-11

Multiply:-3*-4=12

Plus:9+10=19

Plus:7+8=15

Plus:5+6=11

从中我们可以看出各个线程间的竞争关系。而数值并未按我们原先的顺序显示出来这是由于size这个数值被各个线程任意修改的缘故。这也往往是多线程编程要注意的问题。

5 小结

多线程编程是一个很有意思也很有用的技术,使用多线程技术的网络蚂蚁是目前最常用的下载工具之一,使用多线程技术的grep比单线程的grep要快上几倍,类似的例子还有很多。希望大家能用多线程技术写出高效实用的好程序来。

c2c9ed493cd281aa86d8a6f5178c4c01.gif [1] [2] [3] [4] 610626052e95c7fbe3d254abc769d9ad.gif

本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值