4.Linux C多线程的执行顺序问题

来源:互联网 发布:网络课程的优点 编辑:程序博客网 时间:2024/06/04 08:44

先来探究一下最自然状态下(除了pthread_create()不做任何处理)main线程、子线程之间的执行顺序问题!

试验之前不妨来些猜测:

猜测1:执行顺序main Thread > thread_one > thread_two(thread_one比thread_two先创建)

猜测2:它们的执行顺序没有严格的先后顺序

P.S:若猜测1正确,那么在“不对主线程进行阻塞”的情况下,子线程根本没机会执行。

#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>static void thread_one(char* msg);static void thread_two(char* msg);int main(int argc, char** argv){pthread_t th_one, th_two;char * msg = "thread";printf("thread_one starting\n");if (pthread_create(&th_one, NULL, (void*)&thread_one, msg) != 0) {exit(EXIT_FAILURE);}printf("thread_two starting\n");if (pthread_create(&th_two, NULL, (void*)&thread_two, msg) != 0) {exit(EXIT_FAILURE);}printf("Main thread is going over!\n");return 0;}static void thread_one(char* msg){int i = 0;while (i < 6) {printf("I am one. loop %d\n",i);i++;}}static void thread_two(char* msg){int i = 0;while (i < 6) {printf("I am two. loop %d\n",i);i++;}}
编译执行输出结果为:

root@book-desktop:/opt/pc_test/multithreading/5# ./main2
thread_one starting
thread_two starting

Main thread is going over!

此程序情况下,thread_one和thread_two根本没时间执行,是因为主线程结束的时间太快了嘛?

好吧,那在main.c中添加一个大循环吧!main()修改如下:

int main(int argc, char** argv){pthread_t th_one, th_two;char * msg = "thread";printf("thread_one starting\n");if (pthread_create(&th_one, NULL, (void*)&thread_one, msg) != 0) {exit(EXIT_FAILURE);}printf("thread_two starting\n");if (pthread_create(&th_two, NULL, (void*)&thread_two, msg) != 0) {exit(EXIT_FAILURE);}{unsigned int i = 0;while (i < 10000000)i++;}printf("Main thread is going over!\n");return 0;}
执行的输出结果如下:

root@book-desktop:/opt/pc_test/multithreading/5# ./main2

thread_one starting

thread_two starting

I am one. loop 0

I am one. loop 1

I am one. loop 2

I am one. loop 3

I am one. loop 4

I am one. loop 5

I am two. loop 0

I am two. loop 1

I am two. loop 2

I am two. loop 3

I am two. loop 4

I am two. loop 5

Main thread is going over!

root@book-desktop:/opt/pc_test/multithreading/5# ./main2

thread_one starting

thread_two starting

I am two. loop 0

I am two. loop 1

I am two. loop 2

I am two. loop 3

I am two. loop 4

I am two. loop 5

I am one. loop 0

I am one. loop 1

I am one. loop 2

I am one. loop 3

I am one. loop 4

I am one. loop 5

Main thread is going over!

呵呵,两次执行结果不一样!

反复测试,发现结果执行结果总不太一样!

除了thread_one比thread_two先创建之外,显然thread_one和thread_two的地位几乎平等,到了这里,几乎可以得出结论:在“地位平等”的情况下,子线程们的执行顺序是随机的!

子线程的执行顺序是随机的,那么它们是交叉执行的嘛(譬如thread_one执行一会儿再去执行thread_two,接着再回来继续执行...)?继续测试,让thread_one线程和thread_two线程的执行时间更长一点儿。对于main线程又是如何呢?让main线程所干的事情和thread_one和thread_two相同。

修改程序如下:

#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>static void thread_one(char* msg);static void thread_two(char* msg);int main(int argc, char** argv){int i = 0;int j = 0;pthread_t th_one, th_two;char * msg = "thread";printf("thread_one starting\n");if (pthread_create(&th_one, NULL, (void*)&thread_one, msg) != 0) {exit(EXIT_FAILURE);}printf("thread_two starting\n");if (pthread_create(&th_two, NULL, (void*)&thread_two, msg) != 0) {exit(EXIT_FAILURE);}while (i < 6) {printf("I am main. loop %d\n",i);i++;{j = 0;while (j < 10000000)j++;}}printf("Main thread is going over!\n");return 0;}static void thread_one(char* msg){int i = 0;int j = 0;while (i < 6) {printf("I am one. loop %d\n",i);i++;{j = 0;while (j < 10000000)j++;}}}static void thread_two(char* msg){int i = 0;int j = 0;while (i < 6) {printf("I am two. loop %d\n",i);i++;{j = 0;while (j < 10000000)j++;}}}
执行结果如下:

root@book-desktop:/opt/pc_test/multithreading/5# ./main2

thread_one starting

thread_two starting

I am main. loop 0

I am two. loop 0

I am one. loop 0

I am main. loop 1

I am one. loop 1

I am two. loop 1

I am main. loop 2

I am one. loop 2

I am two. loop 2

I am main. loop 3

I am one. loop 3

I am two. loop 3

I am main. loop 4

I am one. loop 4

I am two. loop 4

I am main. loop 5

I am one. loop 5

I am two. loop 5

Main thread is going over!

root@book-desktop:/opt/pc_test/multithreading/5# ./main2

thread_one starting

thread_two starting

I am main. loop 0

I am two. loop 0

I am one. loop 0

I am one. loop 1

I am main. loop 1

I am two. loop 1

I am main. loop 2

I am two. loop 2

I am one. loop 2

I am main. loop 3

I am one. loop 3

I am two. loop 3

I am main. loop 4

I am two. loop 4

I am one. loop 4

I am main. loop 5

I am one. loop 5

I am two. loop 5

Main thread is going over!

两次执行结果不一样!多次测试也发现,具有很大随机性,由此可以确定猜测2是对的!

也即在最自然状态(除了pthread_create()不做任何处理)下main线程、子线程之间的执行顺序没有严格的先后顺序。

所以,若没做特别的阻塞处理,main线程及一系列的子线程,它们的执行顺序是不可预知的!

但在实际中,经常会遇到这样的应用场景:线程1希望线程2达到某种状态时才有机会被执行,其他状态下都是不可执行状态。这就是所谓的线程通信问题。


原创粉丝点击