0

次のことを行うこのコードがあります。

-「e」ノードを含むリンクされたリストを生成し、各ノードにはランダムな値が割り当てられ、ワーカー番号が割り当てられます

-w 個のスレッドを作成し、ノードのワーカー番号が自分のスレッド ID と等しい場合、各スレッドはリストにチェックを入れます。そうであれば、値から sqrt を作成します。

- リストの 5 つまたはすべての値が 2 より小さい場合、メイン スレッドはリストから 2 より小さい要素を削除します。

-一度に実行できるスレッドは 3 つだけです。

コードは次のとおりです。

DWORD WINAPI work(LPVOID argument){
    int tid = *((int *)argument);
    elem* p = head;
    while(p!=NULL){
        if (tid == p->worker){
            WaitForSingleObject(semaphor, 0L);
            double val = p->value;
            p->value = sqrt(val);
            if (p->value < 2){
                EnterCriticalSection(&countMutex);
                count++;
                if(count == maxCount){
                    WakeConditionVariable (&conditionalVar);
                }
                LeaveCriticalSection(&countMutex);
            }       
            Sleep(1);
            ReleaseSemaphore(semaphor, 1L, NULL);
        }
        if (p->next == NULL)
            p = head;
        else 
            p = p->next;
    }

    return NULL;
}

int _tmain(int argc, _TCHAR* argv[])
{
    //generate list, create threads (the threads are assigned to the work function)

    EnterCriticalSection(&countMutex);
    while(e > 0){
        SleepConditionVariableCS(&conditionalVar, &countMutex, INFINITE);
        deleteElements();
        if (e < 5)
            maxCount = e;
        count = 0;
        cout << "After erasure: \n";
        printList();
        cout << "\n";
    }
    LeaveCriticalSection(&countMutex);


    //free space
}

問題は、最初の削除後に、「mainW.cpp.exe の 0x00fe1c8e で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 0xfeeefef2」というエラーが表示されることです。

これは、すでに削除されている値にどこかでアクセスしようとしていることを意味しますが、リストが同期されているため、その理由はわかりません。

4

1 に答える 1

2

ロックなしでリストをトラバースしています。

if (p->next == NULL)
    p = head;
else 
    p = p->next;

メインスレッドが削除された場合はどうなりp->nextますか?

于 2013-01-08T15:15:29.477 に答える