Код (Text): #define _WIN32_WINNT 0x0500 #ifndef UNICODE #define UNICODE #endif #ifndef _UNICODE #define _UNICODE #endif #include <windows.h> #include <stdio.h> #include <wchar.h> #define kCalculationsCount 10 #define kMinN 35 #define kMaxN 45 volatile struct Fibonacci { int thread_index; int n; int fib_of_n; HANDLE done_event; }; int Calculate(int n) { if (n <= 1) return n; return Calculate(n - 1) + Calculate(n - 2); } unsigned int GetLogicalProcessorCount() { return 4; } DWORD WINAPI ThreadPoolCallback(LPVOID thread_context) { struct Fibonacci *pf = thread_context; wprintf(L"Thread [%d] started calculation of Fibonacci(%d)...\n", pf->thread_index, pf->n); pf->fib_of_n = Calculate(pf->n); SetEvent(pf->done_event); wprintf(L"Thread [%d] finished calculation of Fibonacci(%d)...\n", pf->thread_index, pf->n); return 0; } int wmain() { HANDLE done_events[kCalculationsCount]; struct Fibonacci fibonacci_array[kCalculationsCount]; int i; wprintf(L"Launching %d tasks...\n", kCalculationsCount); for (i = 0; i < kCalculationsCount ; ++i) { ULONG queue_flags = WT_EXECUTEDEFAULT; done_events[i] = CreateEvent(NULL, TRUE, FALSE, NULL); fibonacci_array[i].thread_index = i; fibonacci_array[i].n = kMinN + (rand()*(kMaxN - kMinN))/RAND_MAX; fibonacci_array[i].done_event = done_events[i]; WT_SET_MAX_THREADPOOL_THREADS(queue_flags, GetLogicalProcessorCount()); QueueUserWorkItem(ThreadPoolCallback, &fibonacci_array[i], queue_flags); } WaitForMultipleObjects(kCalculationsCount, done_events, TRUE, INFINITE); wprintf(L"All calculations are complete...\n"); for (i = 0; i < kCalculationsCount; ++i) { wprintf(L"Fibonacci(%d) = %d\n", fibonacci_array[i].n, fibonacci_array[i].fib_of_n); } for (i = 0; i < kCalculationsCount; ++i) { CloseHandle(done_events[i]); } return 0; } Собственно, вопрос: нужен ли модификатор volatile при объявлении сруктуры Fibonacci? Если нет, то нужен ли он где-то в другом месте и почему?
Ursus Т.е. должно быть Код (Text): struct Fibonacci { int thread_index; int n; int fib_of_n; HANDLE done_event; }; Код (Text): volatile struct Fibonacci fibonacci_array[kCalculationsCount]; ?
Ezrah Не нужен вообще там volatile. Он нужен в специфических случаях для предотвращения некоторых оптимизаций компилятора.
Хорошо, кажется я понял в каких именно случаях он действительно нужен. В остальном код корректен? И в догонку - есть ли ограничение на количество элементов в очереди пула потоков, или количество определяется объемом доступной физической памяти?