先来探究一下最自然状态下(除了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 startingMain 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达到某种状态时才有机会被执行,其他状态下都是不可执行状态。这就是所谓的线程通信问题。