【发布时间】:2021-07-17 15:58:45
【问题描述】:
我正在尝试用 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;
我对并行编程还很陌生,所以我怀疑我在做一些非常明显和愚蠢的事情。
【问题讨论】:
-
volatile没有解决线程同步问题,不应在 C 中用于该目的。您似乎为此目的正确使用了互斥锁,因此,如果您提供了只访问有问题的数据,那么我认为你的不是同步问题。 -
我确实注意到,在继续使用其结果之前,您未能测试
realloc()是否成功。可能与您的问题有关。 -
总的来说,我们可能需要minimal reproducible example 来提供很大帮助。
-
我现在没有电脑,但一个不错的 YouTube 频道是 Jacob Sorber 频道。你可能想看看这个视频:youtu.be/9axu8CUvOKY我认为它可以帮助你。
-
我的第一个猜测是,您还应该检查来自
pthread_mutex_lock(&mutex);的返回状态,因为它可能会失败。然而,这是一个非常微弱的概率。另一方面,您应该检查您是否在代码的两个部分中都使用了 same 互斥体实例。你如何共享互斥锁?作为公共库中的静态声明,还是仅在一个可执行文件中拥有“全部”?
标签: c multithreading pthreads race-condition