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

如何在C语言中使用pthreads带约束地对数组执行并发操作?

用Pthreads实现数组元素的并发加倍/减半操作(带最大值约束)

这问题在多线程同步里属于典型的条件等待场景,核心是要给每个数组元素独立的同步控制,不然一个元素触发等待会把整个数组的操作都阻塞住,完全没并发意义了。我给你拆解思路,再附上可运行的代码示例。

核心思路

  • 给每个数组元素配对一个pthread_mutex_t(互斥锁)和pthread_cond_t(条件变量):这样每个元素的操作互不干扰,前5个接近最大值的元素触发等待时,不影响后5个元素的正常操作。
  • 加倍操作的逻辑:锁定对应元素的互斥锁后,循环检查元素值的2倍是否超过最大值。如果超过,就调用pthread_cond_wait等待,直到有减半操作修改了值并发出信号;满足条件后执行加倍,最后解锁。
  • 减半操作的逻辑:锁定对应元素的互斥锁后直接执行减半(问题里没提最小值限制),操作完成后调用pthread_cond_signal唤醒可能在等待该元素的加倍线程,最后解锁。
  • 为什么用while循环检查条件?因为条件变量可能出现虚假唤醒,必须重新确认当前元素是否满足加倍的条件。

完整代码示例

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

#define MAX_VALUE 100    // 允许的最大值
#define ARRAY_SIZE 10    // 数组大小
#define DOUBLE_THREADS 2 // 加倍线程数量
#define HALF_THREADS 2   // 减半线程数量

// 每个元素的同步结构
typedef struct {
    int value;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
} Element;

Element array[ARRAY_SIZE];

// 加倍线程函数
void* double_element(void* arg) {
    int thread_id = *(int*)arg;
    free(arg); // 释放传入的线程ID内存

    for (int i = 0; i < 20; i++) { // 每个线程执行20次操作,模拟持续并发
        int idx = rand() % ARRAY_SIZE; // 随机选一个元素操作

        pthread_mutex_lock(&array[idx].mutex);

        // 循环检查:如果加倍后超过最大值,等待
        while (array[idx].value * 2 > MAX_VALUE) {
            printf("加倍线程%d:元素%d当前值%d,加倍会超最大值,等待...\n", 
                   thread_id, idx, array[idx].value);
            pthread_cond_wait(&array[idx].cond, &array[idx].mutex);
        }

        // 执行加倍
        array[idx].value *= 2;
        printf("加倍线程%d:元素%d值变为%d\n", thread_id, idx, array[idx].value);

        pthread_mutex_unlock(&array[idx].mutex);
        usleep(100000); // 模拟操作耗时,让并发效果更明显
    }

    return NULL;
}

// 减半线程函数
void* half_element(void* arg) {
    int thread_id = *(int*)arg;
    free(arg);

    for (int i = 0; i < 20; i++) {
        int idx = rand() % ARRAY_SIZE;

        pthread_mutex_lock(&array[idx].mutex);

        // 直接执行减半(无最小值限制)
        array[idx].value /= 2;
        printf("减半线程%d:元素%d值变为%d\n", thread_id, idx, array[idx].value);

        // 唤醒等待该元素的加倍线程
        pthread_cond_signal(&array[idx].cond);

        pthread_mutex_unlock(&array[idx].mutex);
        usleep(150000);
    }

    return NULL;
}

int main() {
    // 初始化数组:前5个接近最大值,后5个远低于最大值
    for (int i = 0; i < ARRAY_SIZE; i++) {
        if (i < 5) {
            array[i].value = MAX_VALUE - 10; // 90,接近100
        } else {
            array[i].value = 10; // 远低于最大值
        }
        pthread_mutex_init(&array[i].mutex, NULL);
        pthread_cond_init(&array[i].cond, NULL);
    }

    pthread_t double_threads[DOUBLE_THREADS];
    pthread_t half_threads[HALF_THREADS];

    // 创建加倍线程
    for (int i = 0; i < DOUBLE_THREADS; i++) {
        int* id = malloc(sizeof(int));
        *id = i;
        pthread_create(&double_threads[i], NULL, double_element, id);
    }

    // 创建减半线程
    for (int i = 0; i < HALF_THREADS; i++) {
        int* id = malloc(sizeof(int));
        *id = i;
        pthread_create(&half_threads[i], NULL, half_element, id);
    }

    // 等待所有线程完成
    for (int i = 0; i < DOUBLE_THREADS; i++) {
        pthread_join(double_threads[i], NULL);
    }
    for (int i = 0; i < HALF_THREADS; i++) {
        pthread_join(half_threads[i], NULL);
    }

    // 销毁同步结构
    for (int i = 0; i < ARRAY_SIZE; i++) {
        pthread_mutex_destroy(&array[i].mutex);
        pthread_cond_destroy(&array[i].cond);
    }

    printf("\n所有操作完成,最终数组值:\n");
    for (int i = 0; i < ARRAY_SIZE; i++) {
        printf("元素%d:%d\n", i, array[i].value);
    }

    return 0;
}

关键细节说明

  • 独立同步控制:每个元素的互斥锁和条件变量是独立的,这样当某个元素触发等待时,其他元素的线程可以正常操作,保证了并发效率。
  • 虚假唤醒处理:加倍操作里用while而非if检查条件,因为pthread_cond_wait可能在没有收到信号的情况下被唤醒(虚假唤醒),必须重新验证条件。
  • 信号唤醒:减半操作完成后调用pthread_cond_signal,只会唤醒一个等待该元素的线程;如果有多个线程等待,可以用pthread_cond_broadcast,但这里用signal足够,因为每次减半只需要一个加倍线程继续执行。
  • 线程安全的随机选择:示例里用rand()是为了简化,实际生产环境如果需要更公平的随机,建议用线程安全的随机函数(比如rand_r)。

编译运行的话,记得链接pthreads库:

gcc -o array_ops array_ops.c -lpthread
./array_ops

你可以根据实际需求调整线程数量、操作次数,或者改成每个线程固定处理几个元素,核心逻辑都是围绕每个元素的独立条件等待来做的。

内容的提问来源于stack exchange,提问作者Yos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:54:40