实例讲解ptread_mutex_t和pthread_cond_t

上代码:

/*
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

你可能感兴趣的:(pthread)