// Программа из конспекта "Системное программное обеспечение" // Версия для Windows // стр. ?? // Приложение CSTHREADS // многопоточное приложение, синхронизация критическими секциями #include #include #include #define threads 64 // глобальная критическая секция CRITICAL_SECTION cs; // стркутура для обмена данными struct MYDATA { int num; char file[80]; int spaces; } data[threads]; // функция потока DWORD WINAPI threadfunc(LPVOID); int main(int argc, char* argv[]) { // дескрипторы потоков HANDLE hThreads[threads]; // данные для потоков //struct MYDATA data; // вспомогательные переменные int i; DWORD res; if (argc < 3) { printf("Usage: csthreads.exe filename ..."); exit(-1); } // создание критической секции InitializeCriticalSection(&cs); // вход в критическую секцию EnterCriticalSection(&cs); for (i = 0; i < argc - 1; i++) { // вход в критическую секцию //EnterCriticalSection(&cs); // заполнение структуры данных data[i].num = i; strcpy(data[i].file, argv[i + 1]); data[i].file[strlen(argv[i + 1])] = 0; data[i].spaces = -1; // выход из критической скуции, чтобы отработал поток //LeaveCriticalSection(&cs); hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc, (LPVOID)&data[i], 0, NULL); if (hThreads[i] == NULL) { printf("(Main)Cant create thread %d!\n", i); exit(-i); } else printf("(Main)Create thread %d!\n", i); } // выход из критической скуции, чтобы отработал поток LeaveCriticalSection(&cs); // убедимся, что все потоки завершены //WaitForMultipleObjects(argc - 1, hThreads, TRUE, INFINITE); // закрываем дескрипторы потоков for (i = 0; i < argc - 1; i++) { WaitForSingleObject(hThreads[i], INFINITE); // проверка результата GetExitCodeThread(hThreads[i], &res); //printf("(Main)In file %s found spaces %d\n", argv[i+1], (int)res); printf("(Main)In file %s found spaces %d\n", data[i].file, data[i].spaces); CloseHandle(hThreads[i]); } // удаляем критическую секцию DeleteCriticalSection(&cs); } DWORD WINAPI threadfunc(LPVOID num) { //MYDATA data = *((MYDATA *)src); int i = *((int *)num); int total = 0; FILE *hdl; printf("Thread #%d wait CS...\n", i); // захват критической секции EnterCriticalSection(&cs); printf("Thread #%d enter CS! Open file %s...\n", i, data[i].file); if (hdl = fopen(data[i].file, "rt")){ // цикл чтения до конца файла while (!feof(hdl)) { // чтение одного символа из файла if ((char)fgetc(hdl) == 0x20) total++; } printf("(ThreadID: %lu), File %s spaces = %d\n", GetCurrentThreadId(), data[i].file, total); data[i].spaces = total; // закрытие файла fclose(hdl); // освобождение критической секции LeaveCriticalSection(&cs); return total; } else { printf("(ThreadID: %lu), Can't open file %s!\n", GetCurrentThreadId(), data[i].file); LeaveCriticalSection(&cs); ExitThread(-i); } }