You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行中暂停线程版与非线程版程序并使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 14:55:28