2. 使用 QNX 命令行工具进行进程管理
任务目标
在QNX Neutrino实时操作系统中,使用POSIX线程接口创建3个工作线程。每个线程打印自己的线程ID,主线程通过pthread_join等待所有线程结束,以此验证多线程的并发执行与资源回收。
环境依赖
本案例面向QNX 7.x或8.x开发环境,编译需链接POSIX线程库。在QNX Momentics IDE中创建C项目时,需在项目属性中勾选pthread库;若使用命令行编译,需添加-lpthread链接选项。
关键完整代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#define NUM_THREADS 3
/* 线程工作函数:打印自身线程ID */
void* thread_func(void* arg) {
int idx = *(int*)arg;
pthread_t tid = pthread_self();
printf("线程 %d 启动,线程ID: %lu\n", idx, (unsigned long)tid);
sleep(1); /* 模拟工作负载,确保并发可见 */
printf("线程 %d 结束\n", idx);
return NULL;
}
int main(void) {
pthread_t threads[NUM_THREADS];
int thread_args[NUM_THREADS];
int rc;
printf("主线程ID: %lu,创建 %d 个工作线程...\n",
(unsigned long)pthread_self(), NUM_THREADS);
/* 创建线程 */
for (int i = 0; i < NUM_THREADS; i++) {
thread_args[i] = i;
rc = pthread_create(&threads[i], NULL, thread_func, &thread_args[i]);
if (rc != 0) {
fprintf(stderr, "创建线程 %d 失败,错误码: %d\n", i, rc);
return 1;
}
}
/* 等待所有线程结束 */
for (int i = 0; i < NUM_THREADS; i++) {
rc = pthread_join(threads[i], NULL);
if (rc != 0) {
fprintf(stderr, "join线程 %d 失败,错误码: %d\n", i, rc);
return 1;
}
}
printf("所有线程已成功join,主线程退出\n");
return 0;
}
编译与运行
在QNX目标机上,使用以下命令编译并运行:
qcc -o thread_demo thread_demo.c -lpthread
./thread_demo
验证方法与判定标准
运行程序后,观察输出应满足以下条件,即可判定通过:
- 主线程先打印自身ID,随后依次打印3个线程的启动信息,每个线程ID均不同且与主线程ID不同;
- 由于每个线程内部有1秒延时,3个线程的“启动”打印应几乎同时出现(间隔小于1秒),而“结束”打印也几乎同时出现,证明线程并发执行而非串行;
- 程序最终打印“所有线程已成功join,主线程退出”,退出码为0。
若线程创建或join失败,程序会打印错误码并提前退出,此时需检查系统线程资源限制或参数传递是否正确。
关键点说明
线程参数thread_args[i]采用独立数组元素传递,避免多个线程共享同一栈变量导致数据竞争。使用pthread_self()获取线程真实ID,而非使用传入参数,确保打印的是内核分配的线程标识。主线程通过pthread_join阻塞等待每个线程结束,确保所有子线程资源被正确回收后再退出进程。