为什么线程同步不起作用?

时间:2012-01-22 16:02:57

标签: c++ multithreading windows-ce

我编写了一个多线程程序,其中三个线程试图将文本保存到同一个文件中。我应用了关键部分。并且在Windows 7下工作完美,但在CE 6.0中不同步,即每个线程同时尝试保存:

现在有效!!!谢谢大家的帮助!

Emulator

Kernel tracker

关键部分:

InitializeCriticalSection(&CriticalSection);

// Create worker threads
for( i=0; i < THREADCOUNT; i++ )
{
    aThread[i] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) WriteToFile, NULL, 0, &ThreadID);

    if( aThread[i] == NULL )
    {
        printf("CreateThread error: %d\n", GetLastError());
        return 1;
    }
}

// Wait for all threads to terminate
for( i=0; i < THREADCOUNT; i++ )
{
    WaitResult = WaitForSingleObject(aThread[i], INFINITE);

    switch(WaitResult)
    {
        case WAIT_OBJECT_0:
            printf("Thread %d has terminated...\n", i);
         break;

         // Time out
        case WAIT_TIMEOUT:
            printf("The waiting is timed out...\n");
            break;

        // Return value is invalid.
        default:
            printf("Waiting failed, error %d...\n", GetLastError());
            ExitProcess(0);
    }
}

// Close thread handles
for( i=0; i < THREADCOUNT; i++ )
    CloseHandle(aThread[i]);

// Release resources used by the critical section object.
DeleteCriticalSection(&CriticalSection);

线程调用的函数:

DWORD WINAPI WriteToFile( LPVOID lpParam )
{ 
// lpParam not used in this example
UNREFERENCED_PARAMETER(lpParam);

DWORD dwCount=1, dwWaitResult; 

HANDLE hFile; 
char DataBuffer[30];
DWORD dwBytesToWrite;
DWORD dwBytesWritten;

// Request ownership of the critical section.
EnterCriticalSection(&CriticalSection);

    // Write to the file
    printf("Thread %d writing to file...\n", GetCurrentThreadId());

    hFile = CreateFile(TEXT("file.txt"), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

    SetFilePointer(hFile, 0, NULL, FILE_END);

    while( dwCount <= 3 )
    {
        sprintf(DataBuffer, "Theard %d writing %d\n", GetCurrentThreadId(), dwCount);
        dwBytesToWrite = (DWORD)strlen(DataBuffer);

        WriteFile( hFile, DataBuffer, dwBytesToWrite, &dwBytesWritten, NULL);

            printf("Theard %d wrote %d successfully.\n", GetCurrentThreadId(), dwCount);
            }
        }

        dwCount++;
    }

CloseHandle(hFile);             

// Release ownership of the critical section.
LeaveCriticalSection(&CriticalSection);

return TRUE; 
}

1 个答案:

答案 0 :(得分:10)

问题是您将TRUE传递给fWaitAll的{​​{1}}标记。在Windows CE上,不支持此操作:documentation on MSDN表示此标志必须为WaitForMultipleObjectsFALSE因此不会等待,而是返回错误,但您没有检查返回代码。因此,主线程直接通过,关闭句柄并删除关键部分,而“工作”线程仍在运行。调用WaitForMultipleObjects后,关键部分“无法再用于同步”,因此DeleteCriticalSection调用可能不会再阻止,您最终会遇到此处的情景。

在Windows 7上,一切正常,因为EnterCriticalSection调用确实等待所有线程完成。

而不是使用WaitForMultipleObjects,只需在循环中使用WaitForMultipleObjects依次等待每个线程。