2012-01-22 4 views
4

Я написал многопоточную программу, в которой три потока пытаются сохранить текст в том же файле. Я применил критический раздел. А под окнами 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; 
} 
+0

Как вы инициализировали ghCriticalSection? Пожалуйста, напишите код для этого. Благодаря! – hopia

+3

По крайней мере, венгерский неверен, для InitializeCriticalSection требуется указатель на CRITICAL_SECTION, а не указатель на дескриптор. –

+0

У меня: CRITICAL_SECTION ghCriticalSection; –

ответ

10

Проблема в том, что вы передаете TRUE к fWaitAll флаг на WaitForMultipleObjects. В Windows CE это не поддерживается: documentation on MSDN говорит, что этот флаг должен быть FALSE. WaitForMultipleObjects, таким образом, не ждет, но вместо этого возвращает ошибку, но вы не проверяете код возврата. Основной поток, таким образом, проходит прямо, закрывает дескрипторы и удаляет критический раздел, пока потоки «рабочий» все еще работают. После того, как был вызван DeleteCriticalSection, критический раздел «больше не может использоваться для синхронизации», поэтому вызовы EnterCriticalSection, вероятно, больше не блокируются, и в итоге вы получаете сценарий, который у вас есть.

В Windows 7 все работает, потому что вызов WaitForMultipleObjects действительно ждет завершения всех потоков.

Вместо того, чтобы использовать WaitForMultipleObjects, просто используйте WaitForSingleObject в цикле, чтобы подождать каждую нить в свою очередь.

+0

Бинго. Он не проверяет результат своих WaitForMultipleObjects, которые сообщают ему, что есть ошибка. В CE он может ждать любого, он не может дождаться всего. – ctacke

+0

@ Энтони: Хорошая добыча! –

Смежные вопросы