C - 将 void* 转换为 thrd_create() 中的结构

C - cast void* to structure in thrd_create()

我知道有很多关于将 void* 转换为 struct 的问题得到了解答,但我无法使其以正确的方式工作。

好吧,我想创建一个线程来在后台播放音乐。我有一个结构,它收集加载的音乐文件数组以及开始和结束索引:

typedef unsigned char SoundID;
typedef unsigned char SongID;

typedef struct {
    Mix_Music *songs[9]; // array of songs
    SongID startId;      // index of first song to play
    SongID endId;        // index of last song to play
} SongThreadItem;

然后我想通过创建线程并将实际播放歌曲的函数传递给 thread_create() 函数来播放歌曲。

int play_songs(Mix_Music *songs[9], SongID startId, SongID endId, char loop){
    thrd_t thrd;
    SongThreadItem _item;
    SongThreadItem *item = &_item;

    memcpy(item->songs, songs, sizeof(item->songs));
    item->startId = startId;
    item->endId = endId;
    printf("item->startId is %i\n", item->startId);
    printf("item->endId is %i\n", item->endId);
    thrd_create_EC(thrd_create(&thrd, audio_thread_run, item));

    return 0;
}

int audio_thread_run(void *arg){
    SongThreadItem *item = arg; // also tried with = (SongThreadItem *)arg

    printf("item->startId is %i\n", item->startId);
    printf("item->endId is %i\n", item->endId);
    free(item);

    return 0;
}

然后我得到以下输出:

item->startId is 0
item->endId is 8
item->startId is 6
item->endId is 163

audio_thread_run() 中检索到的值不是预期的值。我不知道我是否放了足够多的代码让别人发现我的错误,我尽量减少它,因为它是一个更大项目的一部分。

在此先感谢您的帮助。

SongThreadItem _item;
SongThreadItem *item = &_item; // bug

这是一个问题:您为线程提供了一个指向堆栈变量的指针。堆栈将被主线程中发生的几乎所有事情覆盖。您需要在此处分配动态内存(使用 malloc),并在不再需要时注意释放它(可能在线程例程本身中)。

其他选项将是一个全局结构,用于跟踪所有活动线程及其起始数据,或类似的东西。但它会涉及动态分配,除非线程数在编译时是固定的。

该线程异步运行,但您向它传递了一个指向 SongThreadItem 的指针,该指针位于调用 play_songs().

的线程的堆栈上

如果您只有一个线程调用 play_songs(),并且在您完成 item 之前不会再次调用它,您可以这样定义 _item

static SongThreadItem _item;

这样就在数据段,不会被覆盖

如果您不知道何时以及谁会调用 play_songs(),那么在您完成后只需 malloc _itemfree 它在线程中:

...
SongThreadItem *item = (SongThreadItem *)malloc(sizeof(SongThreadItem));
...

后者通常是更好的主意。将其视为将数据的所有权传递给新线程。当然,如果线程创建失败,生产质量代码应该释放该项目。