C语言中如何使用pthread线程实现并验证并行执行效果
问题排查与解决方案
1. 现有代码的隐藏bug
你两次调用pthread_create都传入了同一个&threads[i],后一次创建的线程ID会直接覆盖前一次的存储值,导致第一个线程的标识直接丢失,后续也无法正常等待两个线程执行结束,这是首先要修正的问题。你可以把threads数组长度调整为2*NUM_THREADS,或者单独定义两个pthread_t变量分别存储两个线程的ID。
2. 看不出并行效果的原因
你编写的两个线程函数逻辑过于轻量化,只有几次打印操作和简单算术运算,CPU执行这些指令只需要几微秒,往往第一个线程在第二个线程还没完成系统调度的时候就已经执行完毕了,所以输出看起来和串行执行没有区别。
3. 观测并行效果的方法
你可以给两个线程函数加入随机时长的休眠,模拟真实业务中线程执行耗时的场景,同时给输出加上时间戳,就能清楚看到两个线程的执行是重叠的,参考修改后的代码:
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> int a = 0, b = 0; void *PrintHello(void *threadid) { long tid = (long)threadid; // 随机睡眠0~2秒,模拟任务处理耗时 sleep(rand() % 3); printf("[%ld秒] 线程%ld(PrintHello)执行:a=%d, b=%d\n", time(NULL)%100, tid, a, b); a += 5; printf("[%ld秒] 线程%ld(PrintHello)执行结束:a修改为%d\n", time(NULL)%100, tid, a); pthread_exit(NULL); } void *PrintHello_2(void *threadid) { long tid = (long)threadid; sleep(rand() % 3); printf("[%ld秒] 线程%ld(PrintHello_2)执行:a=%d, b=%d\n", time(NULL)%100, tid, a, b); b += 3; printf("[%ld秒] 线程%ld(PrintHello_2)执行结束:b修改为%d\n", time(NULL)%100, tid, b); pthread_exit(NULL); } int main() { srand(time(NULL)); pthread_t t1, t2; // 同时创建两个线程 pthread_create(&t1, NULL, PrintHello, (void*)1); pthread_create(&t2, NULL, PrintHello_2, (void*)2); // 等待两个线程都执行完再退出主程序 pthread_join(t1, NULL); pthread_join(t2, NULL); printf("最终结果:a=%d, b=%d\n", a, b); return 0; }
使用命令gcc 代码文件名.c -o test -lpthread编译后多次运行,你会看到两个线程的打印顺序是随机的,有时候PrintHello先执行,有时候PrintHello_2先执行,极端情况下还会出现打印内容交错的情况,这就是多任务并行/并发执行的直观表现。
4. 补充说明
如果你的CPU只有单个核心,系统会通过时间片轮转调度两个线程,属于并发执行;如果是多核CPU,两个线程会被分配到不同核心同时运行,这就是你理解的真正并行。不管是并发还是并行,上述代码执行顺序随机的表现都能证明两个任务不是按固定顺序串行执行的。
内容的提问来源于stack exchange,提问作者IssacCloudVII
相关产品推荐
相关产品推荐

