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

Ubuntu LED控制台出现类Matrix乱码,如何排查线程信号量代码错误?

Troubleshooting Your Matrix-Style Console Glitch

Hey there, let's dig into those weird random characters popping up in your Ubuntu console—plus fix the thread and semaphore issues you're running into. This glitch is almost certainly tied to memory corruption or unsafe thread behavior, so let's break it down step by step.

1. Critical Array Out-of-Bounds Error (Likely the Root Cause)

First up, a big red flag in your main function:

for (i = 0; i < 3; i += 1) {
    rc = pthread_create(&thread[i], NULL, led_toggle_thr, (void *)i);
    assert(rc == 0);
}

You're creating 3 LED toggle threads, but your global arrays flashing and flashing_delay only have 2 elements (indices 0 and 1). The third thread will use id = 2, which means it's accessing flashing[2] and flashing_delay[2]—this is a classic array out-of-bounds access.

Memory corruption from out-of-bounds reads/writes is almost certainly causing those "Matrix-style" random characters in your console. Fix this by only creating 2 LED threads (one for each LED):

// Create threads for LED 0 and 1 only
for (i = 0; i < 2; i += 1) {
    rc = pthread_create(&thread[i], NULL, led_toggle_thr, (void *)i);
    assert(rc == 0);
}

2. Thread Handle Overwrite

Right after creating the 3 LED threads, you overwrite thread[2] with the keyboard thread:

rc = pthread_create(&thread[2], NULL, keyboard_thr, NULL);
assert(rc == 0);

This loses track of the third LED thread's handle, leading to resource leaks and undefined behavior. With the fix above (only 2 LED threads), thread[2] is free for the keyboard thread, so this becomes safe.

3. Unlocked Access to Shared Variables

Your flashing array is a shared variable (likely modified by keyboard_thr to toggle LED states). In led_toggle_thr, you read flashing[id] outside the semaphore critical section:

if (flashing[id]) {
    sem_wait(&mutex);
    led_toggle((leds_t)id);
    sem_post(&mutex);
}

This creates a race condition: the value of flashing[id] could change between the if check and the led_toggle call. Wrap the entire check and action in the semaphore lock to ensure consistency:

sem_wait(&mutex);
if (flashing[id]) {
    led_toggle((leds_t)id);
}
sem_post(&mutex);

4. High-Frequency Console Updates Causing Glitches

Your led_info_thr runs in an infinite loop with no delay, spamming lcd_write_at as fast as possible. This floods the console with updates, compounding memory corruption issues and causing display artifacts. Add a small delay to throttle updates:

void *led_info_thr(void *arg) {
    char flashing_str[2]={'N','N'};
    while(true) {
        sem_wait(&mutex); // Lock once for all shared reads/writes
        for(int i = 0; i < 2; i++) {
            flashing_str[i] = flashing[i] ? 'Y' : 'N';
            lcd_write_at(i, 0, "LED%d F:%c D:%d", i, flashing_str[i], flashing_delay[i]);
        }
        sem_post(&mutex);
        usleep(100000); // 100ms delay to reduce update frequency
    }
    return NULL;
}

I also moved the semaphore lock outside the loop—no need to lock/unlock twice per iteration; locking once is more efficient and safer.

5. Thread Argument Type Safety

When passing i as a thread argument, you cast it to void* then back to unsigned long. On 64-bit systems, this can cause issues since int and void* might be different sizes. A safer approach (optional but good practice):

// In main
for (i = 0; i < 2; i += 1) {
    unsigned long *id = malloc(sizeof(unsigned long));
    *id = i;
    rc = pthread_create(&thread[i], NULL, led_toggle_thr, id);
    assert(rc == 0);
}

// In led_toggle_thr
void *led_toggle_thr(void *arg) {
    unsigned long id = *(unsigned long*)arg;
    free(arg); // Don't forget to free the allocated memory!
    while (true) {
        // ... rest of your code ...
    }
}

Final Quick Checks

  • Make sure sem_init(&mutex, 0, 1); is correctly written (your code had &amp;mutex which is an HTML escape—use &mutex in your actual code).
  • Ensure all shared variables (flashing, flashing_delay) are only accessed within semaphore-locked critical sections in every thread that uses them (including keyboard_thr).

These fixes should eliminate the memory corruption causing the Matrix glitches and resolve your thread/semaphore issues.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:56:22