3. 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释放资源。锁的粒度直接影响性能——本例将锁置于循环内,每次递增都加锁,虽然安全但开销较大;实际工程中可考虑批量累加至局部变量后再一次性提交,以降低锁竞争频率。