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

基于Peterson算法实现双线程共享内存临界区互斥时遇段错误求助

修复Peterson算法线程互斥实现的段错误与同步问题

问题分析

1. 段错误根源

你在创建线程时直接将整数0、1强转为void*传递:

pthread_create(&t1, NULL, switching, (void*)0);
pthread_create(&t2, NULL, switching, (void*)1);

但线程函数中尝试解引用这个指针:

int procNum = *(int*)process;

这相当于访问内存地址0或1的非法区域,直接触发段错误。

2. 同步逻辑的隐藏问题

全局变量flag和turn未加volatile修饰,编译器可能会将这些变量缓存到寄存器,导致线程无法感知其他线程的修改,破坏Peterson算法的互斥正确性。

修复步骤

1. 修正线程参数传递

直接将void*类型的参数强转为整数,无需解引用:

int procNum = (int)process;

2. 阻止编译器优化同步变量

给flag和turn添加volatile修饰,确保每次访问都从内存读取:

volatile int flag[2];
volatile int turn;

3. 修正输出格式(可选)

原代码中printf的换行符错误,修正为\n保证输出整洁。

修复后的完整代码

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

// volatile修饰同步变量,避免编译器优化
volatile int flag[2];
volatile int turn;
int* sharedMemory;

void lock_process(int procNum) {
    flag[procNum] = 1;
    turn = 1 - procNum;
    // Peterson算法等待条件:对方也想进入且轮到对方
    while (flag[1 - procNum] == 1 && turn == 1 - procNum);
}

void unlock_process(int procNum) {
    flag[procNum] = 0;
}

void* switching(void* process) {
    int i = 0;
    // 直接将void*转为线程编号,无需解引用
    int procNum = (int)process;
    printf("Thread Entered: %d\n", procNum);
    
    lock_process(procNum);
    // 临界区:安全操作共享内存
    for (i = 0; i < 1000; i++) {
        (*sharedMemory)++;
    }
    unlock_process(procNum);
    
    return NULL;
}

int main() {
    pthread_t t1, t2;
    flag[0] = 0;
    flag[1] = 0;
    turn = 0;
    
    sharedMemory = (int*)malloc(sizeof(int));
    if (sharedMemory == NULL) {
        perror("malloc error");
        exit(1);
    }
    *sharedMemory = 0;
    
    // 传递整数作为线程参数
    pthread_create(&t1, NULL, switching, (void*)0);
    pthread_create(&t2, NULL, switching, (void*)1);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    
    // 打印最终结果验证互斥效果
    printf("Final sharedMemory value: %d\n", *sharedMemory);
    free(sharedMemory);
    return 0;
}

编译运行

编译时必须链接pthread库:

gcc peterson.c -o peterson -pthread
./peterson

正常运行后会输出Final sharedMemory value: 2000,说明互斥逻辑生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:27:30