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

互斥锁测试代码异常咨询:为何未输出预期内容?

Mutex & Condition Variable Issue: Fixing Your Download/Play Thread Sync

Hey there! Let's break down why your code isn't outputting the full expected message, and walk through how to fix it.

First, let's recap your problem:

You're learning mutex locks, wrote test code that should output downloading..... complete.... start play!, but only get downloading..... complete..... You want to know:

  1. What's causing the error?
  2. How to fix the code?

Based on common pitfalls with pthread condition variables and your code snippet, here's the breakdown:

1. Why Your Code Isn't Working

The core issue almost certainly boils down to missing condition variable signaling plus potential misuses of locks/condition checks:

  • No wake-up for the play thread: Your download thread finishes updating the shared state (buffer) but never tells the waiting play thread that it's ready. The play thread gets stuck waiting indefinitely on pthread_cond_wait(), so it never prints "start play!".
  • Possible lock misuse: If you're modifying buffer without holding the mutex, you create a data race, and the play thread might never see the updated value even if you did signal.
  • Using if instead of while for condition checks: Even if you added a signal, using if could lead to spurious wakeups (rare but allowed by pthread specs) causing unexpected behavior, but the immediate block here is the missing signal.

2. Fixed Code & Explanations

Here's the corrected version of your code, with key fixes highlighted:

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

int buffer = 0;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void* download(void *arg) {
    // Simulate download work (no lock needed here since we're not touching shared data)
    printf("downloading..... ");
    sleep(2); 

    // Lock before modifying shared buffer to avoid race conditions
    pthread_mutex_lock(&lock);
    buffer = 1; // Mark download as complete
    printf("complete....\n");
    // Signal the waiting play thread that the buffer is ready
    pthread_cond_signal(&cond);
    // Unlock after signaling (order doesn't matter here, but unlock when done with shared data)
    pthread_mutex_unlock(&lock);

    return NULL;
}

void* play(void *arg) {
    pthread_mutex_lock(&lock);
    // Use WHILE loop to check condition (critical for handling spurious wakeups)
    while (buffer == 0) {
        // Wait releases the lock temporarily, and re-acquires it when woken
        pthread_cond_wait(&cond, &lock);
    }
    // Now we know buffer is ready, print the message
    printf("start play!\n");
    pthread_mutex_unlock(&lock);

    return NULL;
}

int main() {
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, download, NULL);
    pthread_create(&tid2, NULL, play, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    pthread_mutex_destroy(&lock);
    pthread_cond_destroy(&cond);
    return 0;
}

Key Fixes:

  • Added pthread_cond_signal() in download: This wakes up the waiting play thread once the download is done and the buffer is updated.
  • Protected shared buffer access with mutex: Any read/write to buffer happens while holding the mutex, preventing data races and ensuring visibility of updates across threads.
  • Replaced if with while in play: This handles spurious wakeups (where the thread wakes up without being signaled) by re-checking the condition before proceeding.

When you run this fixed code, you'll get your expected output:

downloading..... complete....
start play!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:59:37