C ++线程 - 崩溃

时间:2015-05-28 15:52:04

标签: c++ multithreading crash

一整天我都试图找到解决方案而没有任何结果。你是唯一的希望。

我必须做基于bass.h库的声音合成器。一切都很好,直到我希望它发挥单独的流。我决定在不同的线程上做这件事:

void Synthezator::play(MonoStream *stream1, MonoStream *stream2)
{
    threadParam data = {stream1, this};
    threadParam data2 = {stream2, this};
    int x = 6;
    DWORD threadId;
    DWORD threadId2;
    //thread first (PlayThread, data);
    //thread second (PlayThread, data2);
    //first.join();
    //second.join();
    CreateThread(NULL, 0, PlayThread, (PVOID) &data, 0, &threadId);
    CreateThread(NULL, 0, PlayThread, (PVOID) &data2, 0, &threadId2);
    getchar();  
}

(评论的作品以同样的方式运作)

只有当两个线程正在工作时,崩溃才会随机发生(随机时刻,而不是每次)。如果我评论其中一个 - 没有崩溃。

PlayThread功能:

DWORD WINAPI Synthezator::PlayThread(PVOID data)
{
    //cout << "kurwa";
    int i=0;
    threadParam* dataNew = (threadParam*) data;
    dataNew->stream->SeekBegin();
    while(!(dataNew->stream->eof()))
    {
        int no = 0;
        note* a = dataNew->stream->Next(&no);
        dataNew->pointer->PlayNote(a, no);
        i++;
    }
} 

PlayNote:

void Synthezator::PlayNote(note* note, int count)
{
    position = new double[count];
    generatorParams params = {synthType, count, note, position, this};
    HSTREAM SignalStream = BASS_StreamCreate (FREQUENCY, 1, 0, &Generator, &params);
    if (SignalStream == 0) throw " Cannot create stream";

    if(note->sound != 0) {
        if (!BASS_ChannelPlay (SignalStream, TRUE)) throw "Cannot play generated sample";
    }
    const int secinusecs = 1000000;
        sleep(secinusecs*floor(note->duration)/1000000);
        usleep(secinusecs*(note->duration-floor(note->duration)));
    if(note->sound != 0) {
        BASS_ChannelStop(SignalStream);
    }
    BASS_StreamFree(SignalStream);
    delete [] position; 
}

如果我评论这一行,那么没有崩溃(但也没有声音):

if (!BASS_ChannelPlay (SignalStream, TRUE)) throw "Cannot play generated sample";

2 个答案:

答案 0 :(得分:0)

创建线程:

threadParam data = {stream1, this};
threadParam data2 = {stream2, this};
CreateThread(NULL, 0, PlayThread, (PVOID) &data, 0, &threadId);
CreateThread(NULL, 0, PlayThread, (PVOID) &data2, 0, &threadId2);

线程内部

dataNew->pointer->PlayNote(a, no);

问题是您在两个不同的位置使用相同的对象PlayNote功能。因此,在线程1完成PlayNote之前,线程2进入PlayNote。 PlayNote中的第一件事是存储在对象中的动态内存分配,因此线程2只是破坏了线程1的指针。此时,线程1的行为变得不确定,并且一旦另一个线程在第一个线程完成该函数并切换指针后切换回上下文,就会发生崩溃。

欢迎使用多线程编程。这是你的帽子。

答案 1 :(得分:0)

如果&a成员是您在不同主题中修改的唯一成员,那么我建议您放回int a行并将位置声明为私有变量:position

这样每个线程都有自己的位置数组。

虽然我必须看到整个代码确定其他成员不会被多个线程修改。