实例讲解ptread_mutex_t和pthread_cond_t

本文通过两个线程并发累加数值的示例,展示了如何使用互斥锁和条件变量来实现线程间的同步,确保数据的一致性和准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上代码:

/*
pthread.c
gcc -lpthread pthread.c -o pthread
*/
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
typedef struct SumObject
{ int sum;
	pthread_mutex_t lock;
}SumObject;
int N1=0;
int N2=500000;
int N3=1000000;
void * add1(void * cnt)
{     

	printf("add1/n");
	pthread_mutex_lock(&(((SumObject*)cnt)->lock));
	printf("add1 lock/n");
	int i;
	for( i=N1;i<N2;i++)
	{(*(SumObject*)cnt).sum+=i;

	}
	pthread_mutex_unlock(&(((SumObject*)cnt)->lock));
	printf("add1 unlock/n");
	pthread_exit(NULL);
	return 0;
}
void * add2(void *cnt)
{     
	int i;
	cnt= (SumObject*)cnt;
	printf("add2/n");
	pthread_mutex_lock(&(((SumObject*)cnt)->lock));
	printf("add2 lock/n");
	for( i=N2;i<N3;i++)
	{    (*(SumObject*)cnt).sum+=i;

	}
	pthread_mutex_unlock(&(((SumObject*)cnt)->lock));
	printf("add2 unlock/n");
	pthread_exit(NULL);
	return 0;
}


int main(void)
{ int i;
	pthread_t ptid1,ptid2;
	int sum=0;
	SumObject cnt;
	pthread_mutex_init(&(cnt.lock),NULL);
	cnt.sum=0;

	pthread_create(&ptid1,NULL,add1,&cnt);
	pthread_create(&ptid2,NULL,add2,&cnt);

	pthread_mutex_lock(&(cnt.lock));
	printf("sum lock/n");
	printf("sum %d/n",cnt.sum);
	pthread_mutex_unlock(&(cnt.lock));
	printf("sum unlock/n");

	pthread_join(ptid1,NULL);
	pthread_join(ptid2,NULL);
	pthread_mutex_destroy(&(cnt.lock));
	return 0;
}
编译后,将pthread运行多次,其出现的运行结果如下:
(运行结果1)
add1
add1 lock
add1 unlock
sum lock
sum 445698416
sum unlock
add2
add2 lock
add2 unlock
 
 
(运行结果2)
add1
add1 lock
add1 unlock
add2
add2 lock
add2 unlock
sum lock
sum 1783293664
sum unlock
 
 
显然,这个程序是无法正确得出两次运行的结果的。也就是说是有BUG的。其原因是这三个线程谁先执行谁后执行是随机的。
主线程的执行不一定需要子线程1,2执行结束。
那么,怎么解决这个问题呢?这个时候可以引入条件变量:
 

/** pthreadcond.cpp** Created on: 2011-8-8* Author: xuxing1*/#include<stdlib.h>#include<stdio.h>#include<unistd.h>#include<pthread.h>typedef struct SumObject { int sum; int flag; pthread_mutex_t lock; pthread_cond_t condition;} SumObject;int N1 = 0;int N2 = 5;int N3 = 10;void * add1(void * cnt) { printf("add1\n"); SumObject *cntp = (SumObject*) cnt; pthread_mutex_lock(&(cntp->lock)); printf("add1 lock\n"); int i; for (i = N1; i <= N2; i++) { (*(SumObject*) cnt).sum += i; sleep(1); } //sleep(3); cntp->flag++; printf("add1 unlock\n"); if (cntp->flag == 2) pthread_cond_signal(&(cntp->condition)); pthread_mutex_unlock(&(cntp->lock)); pthread_exit(NULL); return 0;}void * add2(void *cnt) { int i; SumObject *cntp = (SumObject*) cnt; printf("add2\n"); pthread_mutex_lock(&(cntp->lock)); printf("add2 lock\n"); for (i = N2+1; i <= N3; i++) { (*(SumObject*) cnt).sum += i; sleep(1); } cntp->flag++; printf("add2 unlock\n"); if (cntp->flag == 2) pthread_cond_signal(&(cntp->condition)); pthread_mutex_unlock(&(cntp->lock)); pthread_exit(NULL); return 0;}int main(void) { pthread_t ptid1, ptid2; SumObject cnt; cnt.flag = 0; pthread_mutex_init(&(cnt.lock), NULL); pthread_cond_init(&(cnt.condition), NULL); cnt.sum = 0; pthread_create(&ptid1, NULL, add1, &cnt); pthread_create(&ptid2, NULL, add2, &cnt); pthread_mutex_lock(&(cnt.lock)); while (cnt.flag < 2) { pthread_cond_wait(&cnt.condition, &cnt.lock); printf("sum pthread_cond_wait\n"); } printf("sum lock\n"); printf("sum %d\n", cnt.sum); pthread_mutex_unlock(&(cnt.lock)); printf("sum unlock\n"); pthread_join(ptid1, NULL); pthread_join(ptid2, NULL); return 0;}

请注意,要做多次运行。有时候连续几次都是正确的并不表明代码是正确的。

 
 
除了打印序列不一致之外,其求和结果是正确的。
虽然说Linux提供了这些机制,但是对比而言,感觉基于Linux的多线程编程和Android的多线程差别还是很大的。
 
 
本文的代码参考了http://blogold.chinaunix.net/u2/67780/showart_2211689.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值