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阻塞等待每个线程结束,确保所有子线程资源被正确回收后再退出进程。