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

使用Semaphore实现线程同步的打印序列异常问题求助

修复信号量同步逻辑实现线程循环打印"1234 1234..."

你的代码问题在于信号量的同步逻辑没有严格控制打印顺序:p1在每一轮循环开始时未等待信号量就直接打印"1",同时p2打印完"4"后没有触发下一轮的p1执行,最终导致输出顺序错乱。

以下是两种修复后的实现方案:

方案一:用四个信号量精确控制每一步

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

sem_t s_print1, s_print2, s_print3, s_print4;

void *p1(void *arg) {
    while (1) {
        sem_wait(&s_print1);  // 等待打印1的权限
        printf("1");
        sem_post(&s_print2);  // 通知p2可以打印2

        sem_wait(&s_print3);  // 等待打印3的权限
        printf("3");
        sem_post(&s_print4);  // 通知p2可以打印4
    }
    return NULL;
}

void *p2(void *arg) {
    while (1) {
        sem_wait(&s_print2);  // 等待打印2的权限
        printf("2");
        sem_post(&s_print3);  // 通知p1可以打印3

        sem_wait(&s_print4);  // 等待打印4的权限
        printf("4 ");
        sem_post(&s_print1);  // 触发p1开始下一轮循环
    }
    return NULL;
}

int main() {
    // 初始化:让p1先打印1,其余步骤初始无权限
    sem_init(&s_print1, 0, 1);
    sem_init(&s_print2, 0, 0);
    sem_init(&s_print3, 0, 0);
    sem_init(&s_print4, 0, 0);

    pthread_t t1, t2;

    pthread_create(&t1, NULL, p1, NULL);
    pthread_create(&t2, NULL, p2, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    sem_destroy(&s_print1);
    sem_destroy(&s_print2);
    sem_destroy(&s_print3);
    sem_destroy(&s_print4);

    return 0;
}

修复关键点:

  • 每个打印步骤对应独立信号量,只有收到前一步的通知(sem_post)才能执行当前打印,严格保证1→2→3→4的顺序。
  • p2打印完"4 "后,通过sem_post(&s_print1)触发p1开始下一轮,形成完整循环。
  • 初始信号量s_print1设为1,确保程序启动后p1先执行。

方案二:用两个信号量简化实现

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

sem_t sem_p1, sem_p2;

void *p1(void *arg) {
    while (1) {
        sem_wait(&sem_p1);
        printf("1");
        sem_post(&sem_p2);

        sem_wait(&sem_p1);
        printf("3");
        sem_post(&sem_p2);
    }
    return NULL;
}

void *p2(void *arg) {
    while (1) {
        sem_wait(&sem_p2);
        printf("2");
        sem_post(&sem_p1);

        sem_wait(&sem_p2);
        printf("4 ");
        sem_post(&sem_p1);
    }
    return NULL;
}

int main() {
    sem_init(&sem_p1, 0, 1);  // 初始允许p1执行
    sem_init(&sem_p2, 0, 0);

    pthread_t t1, t2;

    pthread_create(&t1, NULL, p1, NULL);
    pthread_create(&t2, NULL, p2, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    sem_destroy(&sem_p1);
    sem_destroy(&sem_p2);

    return 0;
}

简化逻辑说明:

  • sem_p1控制p1的打印权限,sem_p2控制p2的打印权限。
  • 交替释放信号量:p1打印后给p2权限,p2打印后给p1权限,同样能严格保证1→2→3→4的顺序循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 13:11:02