本实验创建了3个进程,为了更好的描述线程之间的并行执行, 让3个线程共用同一个执行函数。每个线程都有5次循环(可以看成5个小任务), 每次循环之间会随机等待1~10s的时间,意义在于模拟每个任务的到达时间是随机的,并没有任何特定的规律。使用互斥锁mutex完成互斥访问
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 #define THREAD_NUMBER 3 //线程数 6 #define REPAT_NUMBER 5 //每个线程中的小任务数 7 #define DELAY_TIME_LEVELS 10.0 //小任务之间的最大时间间隔 8 pthread_mutex_t mutex; //定义一格互斥锁的全局变量 9 10 //线程函数例程 11 void *func(void *arg) 12 { 13 int thrd_num=(int )arg; 14 int delay_time=0; 15 int count=0; 16 int res; 17 //互斥锁上锁 18 res=pthread_mutex_lock(&mutex); 19 if(res!=0){ 20 printf("Thread %d lock failed. ",thrd_num); 21 pthread_exit(NULL); 22 } 23 //下面这段代码才是共享区 24 printf("thread %d is starting ", thrd_num); 25 for(count=0; count<REPAT_NUMBER; count++){ 26 delay_time=(int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX))+1; 27 sleep(delay_time); 28 printf(" thread %d:job %d delay %d ", thrd_num, count, delay_time); 29 } 30 printf("thread %d finished ",thrd_num); 31 //互斥锁的解锁留给了主线程 32 pthread_mutex_unlock(&mutex); 33 pthread_exit(NULL); //线程退出 34 } 35 36 int main(int argc, char const *argv[]) 37 { 38 pthread_t thread[THREAD_NUMBER]; //存放线程ID 39 int no,res; 40 void *thrd_ret; 41 srand(time(NULL)); 42 43 for(no=0; no<THREAD_NUMBER; no++){ 44 //创建多线程 45 res=pthread_create(&thread[no],NULL,(void *)func,(void *)no); 46 if(res!=0){ 47 printf("create thread %d failed. ", no); 48 exit(res); 49 } 50 } 51 52 printf("create thread success waiting for thread to finish... "); 53 for(no=0; no<THREAD_NUMBER; no++){ 54 //等待线程结束 55 res=pthread_join(thread[no],&thrd_ret); 56 if(!res){ 57 printf("thread %d finished ", no); 58 }else{ 59 printf("thread %d join failed. ", no); 60 } 61 //互斥锁解锁 62 // pthread_mutex_unlock(&mutex); 63 } 64 return 0; 65 }
这里要注意32行和62行的解锁,如果使用的是32行注释掉62行,则程序能正常运行
但如果使用的是62行而注释掉32行的话,程序会在某个地方卡住,运行了13次,下面第二种情况只出现了2次。
猜想:只要thread 2 结束了,在main函数里的for循环也就结束了。那main就return了,这样,剩下还没运行的子线程就被杀死不执行。
不过,从执行成功的情况来看,以上猜想不成立……