如何在运行中暂停线程版与非线程版程序并使用ps命令对比?
问题描述
我写了两个功能一致的C程序,一个用线程实现,另一个不用。作业要求在程序运行时暂停它们,用ps命令对比分析,但程序执行太快,没法用^Z快捷键暂停。想知道可行的实现方法,用sleep这类函数有没有帮助,会不会影响ps的结果?以下是我的代码,可以修改:
无线程版本
#include <stdio.h> int main(void) { int mat[100][100]; // 声明数组 // 生成数组值 for (int row = 0; row < 100; row++) { for (int col = 0; col < 100; col++) { mat[row][col] = row * 5 + col / 3 + col; } } // 求和 int sum = 0; for (int row = 0; row < 100; row++) { for (int col = 0; col < 100; col++) { sum += mat[row][col]; } } // 打印结果 printf("Sum of all values in mat: %d\n", sum); return 0; }
带线程版本
#include <stdio.h> #include <pthread.h> #define NUM_THREADS 100 // 线程数(每个列一个线程) #define ROWS 100 // 数组行数 #define COLS 100 // 数组列数 int mat[ROWS][COLS]; // 存储数据的数组 int sums[COLS]; // 存储每列求和结果的数组 // 线程函数:对某一列求和 void* sum_column(void* arg) { int col = (int)arg; // 获取要处理的列 // 列求和 int sum = 0; for (int row = 0; row < ROWS; row++) { sum += mat[row][col]; } // 存储结果 sums[col] = sum; return NULL; } int main(void) { pthread_t threads[NUM_THREADS]; // 线程数组 // 生成数组值 for (int row = 0; row < ROWS; row++) { for (int col = 0; col < COLS; col++) { mat[row][col] = row * 5 + col / 3 + col; } } // 为每列创建求和线程 for (int col = 0; col < COLS; col++) { pthread_create(&threads[col], NULL, sum_column, (void*)col); } // 等待所有线程结束 for (int col = 0; col < COLS; col++) { pthread_join(threads[col], NULL); } // 汇总所有列的和 int sum = 0; for (int col = 0; col < COLS; col++) { sum += sums[col]; } // 打印结果 printf("Sum of all values in mat: %d\n", sum); return 0; }
可行的实现方法
1. 插入sleep延迟(最简单直接)
在程序的关键执行节点(比如数组生成后、求和前)添加sleep()函数,让程序暂停一段时间,给你足够时间用^Z暂停或执行ps命令。
对ps结果的影响
sleep只会让进程进入睡眠状态(S状态),但完全不影响你要对比的核心信息:无线程版本的进程线程数为1,带线程版本的进程线程数为101(主线程+100个工作线程)。用ps -Lf <PID>依然能清晰看到两者的线程数量差异,睡眠状态不影响作业要求的对比分析。
修改后的代码示例
无线程版本(添加sleep)
#include <stdio.h> #include <unistd.h> // 引入sleep的头文件 int main(void) { int mat[100][100]; // 生成数组值 for (int row = 0; row < 100; row++) { for (int col = 0; col < 100; col++) { mat[row][col] = row * 5 + col / 3 + col; } } sleep(30); // 暂停30秒,留足操作时间 // 求和 int sum = 0; for (int row = 0; row < 100; row++) { for (int col = 0; col < 100; col++) { sum += mat[row][col]; } } printf("Sum of all values in mat: %d\n", sum); return 0; }
带线程版本(添加sleep)
#include <stdio.h> #include <pthread.h> #include <unistd.h> #define NUM_THREADS 100 #define ROWS 100 #define COLS 100 int mat[ROWS][COLS]; int sums[COLS]; void* sum_column(void* arg) { int col = (int)arg; int sum = 0; for (int row = 0; row < ROWS; row++) { sum += mat[row][col]; } sums[col] = sum; sleep(10); // 线程完成计算后暂停,避免主线程过快结束 return NULL; } int main(void) { pthread_t threads[NUM_THREADS]; // 生成数组值 for (int row = 0; row < ROWS; row++) { for (int col = 0; col < COLS; col++) { mat[row][col] = row * 5 + col / 3 + col; } } // 创建所有线程 for (int col = 0; col < COLS; col++) { pthread_create(&threads[col], NULL, sum_column, (void*)col); } sleep(30); // 暂停30秒,此时所有线程已创建,方便用ps查看线程数 // 等待线程结束 for (int col = 0; col < COLS; col++) { pthread_join(threads[col], NULL); } int sum = 0; for (int col = 0; col < COLS; col++) { sum += sums[col]; } printf("Sum of all values in mat: %d\n", sum); return 0; }
2. 用信号等待(更灵活)
让程序等待自定义信号(比如SIGUSR1)再继续执行,你可以先查看ps信息,再手动发送信号让程序跑完。这种方法完全由你控制暂停时机。
修改后的示例(无线程版本)
#include <stdio.h> #include <signal.h> #include <unistd.h> // 空的信号处理函数,仅用于唤醒pause void handle_signal(int sig) {} int main(void) { int mat[100][100]; // 注册SIGUSR1信号的处理函数 signal(SIGUSR1, handle_signal); // 生成数组值 for (int row = 0; row < 100; row++) { for (int col = 0; col < 100; col++) { mat[row][col] = row * 5 + col / 3 + col; } } printf("程序已暂停,发送SIGUSR1信号继续:kill -USR1 %d\n", getpid()); pause(); // 等待信号,进程会一直暂停直到收到信号 // 求和 int sum = 0; for (int row = 0; row < 100; row++) { for (int col = 0; col < 100; col++) { sum += mat[row][col]; } } printf("Sum of all values in mat: %d\n", sum); return 0; }
运行后,程序会打印自身PID,你可以先用ps -Lf <PID>查看进程/线程信息,再执行kill -USR1 <PID>让程序继续。
3. 增大计算量(无需修改逻辑)
把数组规模从100x100改成10000x10000(注意栈空间限制,建议用malloc动态分配),这样程序的计算时间会大幅延长,你有足够时间用^Z暂停。
总结
sleep是最简便的方案,仅改变进程状态,不影响ps要对比的核心信息(线程数、PID等)。- 信号等待能让你精准控制暂停时机,适合需要仔细分析的场景。
- 增大计算量适合不想修改代码逻辑的情况,但会占用更多系统资源。
内容的提问来源于stack exchange,提问作者Feras
相关产品推荐
相关产品推荐

