首页 > 解决方案 > 如何使用 pthreads 从 C 中的另一个线程安全地修改字符串?

问题描述

我正在尝试在 C 中创建一个简单的 CLI 音乐播放器。除了负责播放音乐的主线程之外,我还创建了第二个线程。第二个线程接收这样的参数(我尝试过使用和不使用 volatile 关键字):

typedef struct AUDIO_S
{
    volatile char audio_path[MAX_PATH];
    volatile int play_state;
} audio_t;

主线程可能会更新音频路径(当前文件)和播放状态(播放/暂停)。第二个线程的工作是检测这种变化,并通过改变、播放或暂停歌曲来采取相应的行动。

我有一个问题(我假设)正在发生的事情是第二个线程在读取这些数据的同时,它正在被主线程写入,这会产生乱码输出。我尝试实现一个条件变量,但我仍然得到不好的输出。

这是我编写数据的代码:

extern pthread_mutex_t mutex;
extern pthread_cond_t cond;

pthread_mutex_lock(&mutex);

strcpy(audio->audio_path, state->cur_play_dir);
strcat(audio->audio_path, "/");
strcat(audio->audio_path, state->cur_play_file);
audio->play_state = MUSIC_PLAY;

pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

这是我阅读它的代码:

extern pthread_mutex_t mutex;
extern pthread_cond_t cond;

while (1)
{
    pthread_mutex_lock(&mutex);
    pthread_cond_wait(&cond, &mutex);

    char *new_audio_path = audio->audio_path;
    if (strcmp(new_audio_path, cur_audio_path))
    {               
        cur_audio_path = realloc(cur_audio_path,
                                strlen(new_audio_path) + 1);

        strcpy(cur_audio_path, audio->audio_path);
        printw("PATH: %s\n", cur_audio_path);
    }

    pthread_mutex_unlock(&mutex);
}

互斥锁和条件被声明为全局变量,如下所示:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

我对并行编程相当陌生,所以我怀疑我正在做一些非常明显和愚蠢的事情。

标签: cmultithreadingpthreadsrace-condition

解决方案


在这个问题上睡觉后,我意识到我的错误。事实证明,存储在路径字符串中的数据实际上根本没有问题。

在第二个线程中,我打印到 stdout 的路径值纯粹是为了检查该值是否有效(所以我忘了锁定任何东西)。但是,在主线程中,我还将其他数据打印到标准输出。

由于两个线程都写入标准输出,打印时数据出现乱码,而实际上存储在内存中的数据没有问题。我通过在第一个线程写入标准输出时写入第二个线程中的文本文件来验证这一点。写入文本文件的数据没有问题。


推荐阅读