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

本文通过实验分析了在多线程编程中,主线程与子线程执行顺序的不确定性,揭示了在不进行特别阻塞处理的情况下,线程执行顺序的随机性,并探讨了子线程间的交叉执行可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值