#include #include #define THREADCOUNT 2 HANDLE mutex; DWORD WINAPI WriteToDatabase(LPVOID); int main(void) { setlocale(LC_ALL, "RUSSIAN"); HANDLE threads[THREADCOUNT]; DWORD threadID; int i; // Создаем мьютекс без начального владельца mutex = CreateMutex( NULL, // Структура, которая определяет безопасность (NULL - по умолчанию) FALSE, // Нет начального вледльца NULL); // Имя мьютекста if (mutex == NULL) { std::cerr << "Не удалось создать мьютекс: " << (int) GetLastError() << std::endl;; return 1; } // Создаем потоки for (i = 0; i < THREADCOUNT; i++) { threads[i] = CreateThread( NULL, // Структура, которая определяет безопасность (NULL - по умолчанию) 0, // Размер стека (0 - стандартное значение) (LPTHREAD_START_ROUTINE)WriteToDatabase, // Указатель на фунцию, которая выполнится в потоке NULL, // Аргументы функции 0, // Флаги, которые управляют созданием потока. &threadID); // Указатель на переменную, в которую передастся номер потока // Если поток не создался if (threads[i] == NULL) { std::cerr << "Не удалось создать поток: " << (int) GetLastError() << std::endl; return 1; } std::cout << "Создан поток " << (int)threadID << std::endl; } // Ждем пока все потоки завершат свою работу WaitForMultipleObjects(THREADCOUNT, threads, TRUE, INFINITE); // Уничтожаем потоки for (i = 0; i < THREADCOUNT; i++) { CloseHandle(threads[i]); } // Уничтожаем мьютекс CloseHandle(mutex); system("pause"); return 0; } DWORD WINAPI WriteToDatabase(LPVOID lpParam) { // lpParam not used in this example UNREFERENCED_PARAMETER(lpParam); DWORD waitResult; // Блокируем мьютекс waitResult = WaitForSingleObject( mutex, // Мьютекс INFINITE); // Бесконечное время блокировки switch (waitResult) { // Мьютекс case WAIT_OBJECT_0: __try { // Выполняем функцию std::cout << "Выполняется функция в потоке " << GetCurrentThreadId() << std::endl; } __finally { // Освобождаем сокет if (!ReleaseMutex(mutex)) { std::cerr << "Ошибка при освобождении мьютекса" << std::endl; } } break; // The thread got ownership of an abandoned mutex // The database is in an indeterminate state case WAIT_ABANDONED: return FALSE; } return TRUE; }