3. QNX 进程创建与进程间通信基础

QNX 进程创建与进程间通信基础 学习卡片

任务目标

创建3个线程,各自对同一个全局计数器执行100万次递增操作。若不加以保护,最终计数将因竞态条件而小于300万;使用pthread_mutex互斥锁保护临界区后,最终计数必须精确等于300万。

核心实现

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define THREAD_NUM  3
#define INCREMENTS  1000000

static long counter = 0;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void* worker(void* arg) {
    (void)arg;
    for (int i = 0; i < INCREMENTS; i++) {
        pthread_mutex_lock(&lock);
        counter++;
        pthread_mutex_unlock(&lock);
    }
    return NULL;
}

int main(void) {
    pthread_t tids[THREAD_NUM];

    for (int i = 0; i < THREAD_NUM; i++) {
        if (pthread_create(&tids[i], NULL, worker, NULL) != 0) {
            perror("pthread_create");
            return EXIT_FAILURE;
        }
    }

    for (int i = 0; i < THREAD_NUM; i++) {
        pthread_join(tids[i], NULL);
    }

    printf("counter = %ld (expected %d)\n", counter, THREAD_NUM * INCREMENTS);
    return (counter == THREAD_NUM * INCREMENTS) ? EXIT_SUCCESS : EXIT_FAILURE;
}

编译与运行

qcc -o mutex_demo mutex_demo.c -lpthread
./mutex_demo

在QNX Neutrino环境下,也可使用qcc -Vgcc_ntox86_64指定目标架构后交叉编译。

验证方法

  • 程序退出码为0,表示计数正确;非0表示计数错误。
  • 终端输出应为:counter = 3000000 (expected 3000000)。
  • 可临时注释掉pthread_mutex_lock/unlock两行重新编译运行,观察输出值小于300万,以此确认竞态确实存在且互斥锁生效。

关键说明

互斥锁保证同一时刻只有一个线程进入临界区,使counter++的读-改-写操作成为原子序列。本例使用静态初始化器PTHREAD_MUTEX_INITIALIZER,无需显式调用pthread_mutex_init;若在堆上动态创建锁,则需配对调用pthread_mutex_destroy释放资源。锁的粒度直接影响性能——本例将锁置于循环内,每次递增都加锁,虽然安全但开销较大;实际工程中可考虑批量累加至局部变量后再一次性提交,以降低锁竞争频率。