上代码:
/*
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。