// Программа из конспекта "Системное программное обеспечение" // Версия для Windows // стр. ?? // Приложение MTHREADS // многопоточное приложение, синхронизация мьютексами #define _CRT_SECURE_NO_WARNINGS #include #include #include #define threads 64 // глобальный мьютекс HANDLE hMutex; // стркутура для обмена данными 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: mthreads.exe filename ..."); exit(-1); } // создание мьютекса hMutex = CreateMutex(NULL, FALSE, NULL); // захват мьютекса WaitForSingleObject(hMutex, INFINITE); for (i = 0; i < argc - 1; i++) { // захват мьютекса //WaitForSingleObject(hMutex, INFINITE); // заполнение структуры данных data[i].num = i; strcpy(data[i].file, argv[i + 1]); data[i].file[strlen(argv[i + 1])] = 0; data[i].spaces = -1; //ReleaseMutex(hMutex); hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc, (LPVOID)&data[i], 0, NULL); if (hThreads[i] == NULL) { printf("Cant create thread %d!\n", i); exit(-i); } else printf("(Main)Create thread %d!\n", i); } // освобождение мьютекса, чтобы отработали потоки ReleaseMutex(hMutex); // удаляем мьютекс CloseHandle(hMutex); // закрываем дескрипторы потоков 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]); } } DWORD WINAPI threadfunc(LPVOID num) { //MYDATA data = *((MYDATA *)src); int i = *((int*)num); //data.num; int total = 0; FILE* hdl; printf("Thread #%d wait mutex...\n", i); // захват мьютекса WaitForSingleObject(hMutex, INFINITE); printf("Thread #%d catch mutex! 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); // освобождение мьютекса ReleaseMutex(hMutex); return total; } else { printf("(ThreadId: %lu), Can't open file %s!\n", GetCurrentThreadId(), data[i].file); // освобождение мьютекса, иначе он - покинутый! ReleaseMutex(hMutex); ExitThread(-i); } }