Исходник
[SOURCE="c"]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define NumThreads 4
#define MaxElements 20
#define mutex_lock(mutex) (WaitForSingleObject((*(mutex)), INFINITE))
#define mutex_unlock(mutex) (ReleaseMutex(*(mutex)))
#define mutex_destroy(mutex) (CloseHandle(*(mutex)))
HANDLE ghThreads[ NumThreads ];
int iCurrEntry = 0;
char *Files[ MaxElements ];
typedef HANDLE mutex_t;
mutex_t hMutex;
int mutex_init( mutex_t *mutex )
{
*mutex = CreateMutex( NULL, FALSE, NULL );
return *mutex == NULL;
}
// Ждём случайное количество мс
int RandomWait( void )
{
int wait_Ms;
clock_t end_time;
wait_Ms = rand() % 500 + 1;
//wait_Ms = 1000;
//wait_Ms = 500;
end_time = clock() + wait_Ms;
while ( clock() < end_time )
{};
return wait_Ms;
}
// Функция для потока
DWORD WINAPI ForThread( LPVOID lpParam )
{
TCHAR *FileName;
UNREFERENCED_PARAMETER(lpParam);
mutex_lock( &hMutex );
while ( iCurrEntry < MaxElements )
{
FileName = Files[ iCurrEntry ];
mutex_unlock( &hMutex );
printf( "%s / %d (waited: %d ms)\n", FileName, MaxElements, RandomWait() );
mutex_lock( &hMutex );
iCurrEntry++;
}
mutex_unlock( &hMutex );
return 0;
}
// Создаем потоки
void CreateThreads(void)
{
int i;
mutex_init( &hMutex );
for( i = 0; i < NumThreads; i++ )
{
ghThreads = CreateThread(NULL, // default security
0, // default stack size
ForThread, // name of the thread function
NULL, // no thread parameters
0, // default startup flags
NULL);
if ( ghThreads == NULL )
{
printf( "CreateThread failed (%d)\n", (int)GetLastError() );
return;
}
}
}
// Закрываем все хэндлы потоков
void CloseEvents( void )
{
int i;
for ( i = 0; i < NumThreads; i++ )
CloseHandle( ghThreads[ i ] );
mutex_destroy( &hMutex );
}
// Заполняем массив
void PopulateList( char **List )
{
int i;
char buffer[128];
for ( i = 0; i < MaxElements; i++ )
{
sprintf( buffer, "%3d", i );
List = strdup( buffer );
}
}
// Освобождаем память
void FreeList( char **List )
{
int i;
for ( i = 0; i < MaxElements; i++ )
free( List );
}
// Главная функция
int main( void )
{
DWORD dwWaitResult;
/* initialize random seed: */
srand ( time(NULL) );
PopulateList( Files );
CreateThreads();
dwWaitResult = WaitForMultipleObjects(
NumThreads, // number of handles in array
ghThreads, // array of thread handles
TRUE, // wait until all are signaled
INFINITE);
switch (dwWaitResult)
{
// All thread objects were signaled
case WAIT_OBJECT_0:
printf( "All threads ended, cleaning up for application exit...\n" );
break;
// An error occurred
default:
printf( "WaitForMultipleObjects failed (%d)\n", (int)GetLastError() );
return 1;
}
CloseEvents();
FreeList( Files );
return EXIT_SUCCESS;
}[/SOURCE]
Глючит раскраска что-то на форуме.
При запуске стартуют несколько потоков, но вот они почему-то стартуют одновременно и выводится на экран нулевой элемент. Т.е. этот элемент обрабатывается несколько раз, хотя должен обрабатываться только один раз.
Однако все последующие элементы обрабатываются по одному разу. В функцию для потока я добавил случайную задержку, типа эмуляция какого-нибудь важного процесса.
Если увеличить количество потоков (NumThreads), то нулевой элемент массива тоже будет обрабатываться бОльшее количество раз.
В чём прикол?
[SOURCE="c"]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define NumThreads 4
#define MaxElements 20
#define mutex_lock(mutex) (WaitForSingleObject((*(mutex)), INFINITE))
#define mutex_unlock(mutex) (ReleaseMutex(*(mutex)))
#define mutex_destroy(mutex) (CloseHandle(*(mutex)))
HANDLE ghThreads[ NumThreads ];
int iCurrEntry = 0;
char *Files[ MaxElements ];
typedef HANDLE mutex_t;
mutex_t hMutex;
int mutex_init( mutex_t *mutex )
{
*mutex = CreateMutex( NULL, FALSE, NULL );
return *mutex == NULL;
}
// Ждём случайное количество мс
int RandomWait( void )
{
int wait_Ms;
clock_t end_time;
wait_Ms = rand() % 500 + 1;
//wait_Ms = 1000;
//wait_Ms = 500;
end_time = clock() + wait_Ms;
while ( clock() < end_time )
{};
return wait_Ms;
}
// Функция для потока
DWORD WINAPI ForThread( LPVOID lpParam )
{
TCHAR *FileName;
UNREFERENCED_PARAMETER(lpParam);
mutex_lock( &hMutex );
while ( iCurrEntry < MaxElements )
{
FileName = Files[ iCurrEntry ];
mutex_unlock( &hMutex );
printf( "%s / %d (waited: %d ms)\n", FileName, MaxElements, RandomWait() );
mutex_lock( &hMutex );
iCurrEntry++;
}
mutex_unlock( &hMutex );
return 0;
}
// Создаем потоки
void CreateThreads(void)
{
int i;
mutex_init( &hMutex );
for( i = 0; i < NumThreads; i++ )
{
ghThreads = CreateThread(NULL, // default security
0, // default stack size
ForThread, // name of the thread function
NULL, // no thread parameters
0, // default startup flags
NULL);
if ( ghThreads == NULL )
{
printf( "CreateThread failed (%d)\n", (int)GetLastError() );
return;
}
}
}
// Закрываем все хэндлы потоков
void CloseEvents( void )
{
int i;
for ( i = 0; i < NumThreads; i++ )
CloseHandle( ghThreads[ i ] );
mutex_destroy( &hMutex );
}
// Заполняем массив
void PopulateList( char **List )
{
int i;
char buffer[128];
for ( i = 0; i < MaxElements; i++ )
{
sprintf( buffer, "%3d", i );
List = strdup( buffer );
}
}
// Освобождаем память
void FreeList( char **List )
{
int i;
for ( i = 0; i < MaxElements; i++ )
free( List );
}
// Главная функция
int main( void )
{
DWORD dwWaitResult;
/* initialize random seed: */
srand ( time(NULL) );
PopulateList( Files );
CreateThreads();
dwWaitResult = WaitForMultipleObjects(
NumThreads, // number of handles in array
ghThreads, // array of thread handles
TRUE, // wait until all are signaled
INFINITE);
switch (dwWaitResult)
{
// All thread objects were signaled
case WAIT_OBJECT_0:
printf( "All threads ended, cleaning up for application exit...\n" );
break;
// An error occurred
default:
printf( "WaitForMultipleObjects failed (%d)\n", (int)GetLastError() );
return 1;
}
CloseEvents();
FreeList( Files );
return EXIT_SUCCESS;
}[/SOURCE]
Глючит раскраска что-то на форуме.
При запуске стартуют несколько потоков, но вот они почему-то стартуют одновременно и выводится на экран нулевой элемент. Т.е. этот элемент обрабатывается несколько раз, хотя должен обрабатываться только один раз.
Однако все последующие элементы обрабатываются по одному разу. В функцию для потока я добавил случайную задержку, типа эмуляция какого-нибудь важного процесса.
Если увеличить количество потоков (NumThreads), то нулевой элемент массива тоже будет обрабатываться бОльшее количество раз.
В чём прикол?
Последнее редактирование: