Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Объекты синхронизации и функции ожидания в Windows
Вариант 1 Написать программы для консольного процесса Boss (Резидент) и консольных процессов Scout (Шпион). Для моделирования передачи сообщений ввести специальные события, которые обозначают «точку» и «тире», конец сеанса. Процесс Boss :
Процесс Scout:
Вариант 2 Написать программы для консольного процесса Boss (Резидент) и консольных процессов Scout (Шпион). Для моделирования передачи сообщений ввести специальные события, которые обозначают «1», «2» и конец сеанса для процессов Scout Процесс Boss :
Процесс Scout :
Вариант 3 Написать программы для консольного процесса Boss (Резидент) и консольных процессов Scout (Шпион). Для моделирования передачи сообщений ввести специальные события, которые обозначают любые 4 цифры (на выбор). Процесс Boss:
Процесс Scout:
Вариант 4 Написать программы для консольного процесса Boss и консольных процессов Employee. Для моделирования передачи сообщений ввести специальные события, которые «0», «1», «2», «3» и конец сеанса для процессов Employee. Процесс Boss:
Процесс Employee:
Вариант 5 Написать программы для консольного процесса Administrator и процессов Writer. Для моделирования передачи сообщений ввести специальные события, которые обозначают сообщение «A», сообщение «B» и конец сеанса для процесса Writer. Одновременно принимать и отправлять сообщения может только один процесс Writer, передача остальных сообщений от других процессов должна блокироваться с помощью мьютексов; Процесс Administrator :
Процесс Writer :
Вариант 6 Написать программы для консольного процесса Boss и консольных процессов Employee. Для моделирования передачи сообщений ввести специальные события, которые «0», «1», «2», «3» и конец сеанса для процессов Employee. Процесс Boss :
Процесс Employee :
Вариант 7 Написать программы для консольного процесса Administrator и процессов Writer. Для моделирования передачи сообщений ввести специальные события, которые обозначают сообщение « + », сообщение «–», и конец сеанса для процесса Writer. Одновременно принимать и отправлять сообщения может только один процесс Writer, передача остальных сообщений от других процессов должна блокироваться с помощью мьютексов; Процесс Administrator :
Процесс Writer :
Вариант 8 Написать программы для консольного процесса Administrator и процессов Writer. Для моделирования передачи сообщений ввести специальные события, которые обозначают сообщение « + », сообщение «–», «*», «/» и конец сеанса для процесса Writer. Одновременно принимать и отправлять сообщения могут только два процесса Writer, передача остальных сообщений от других процессов должна блокироваться; Процесс Administrator :
Процесс Writer :
Вариант 9 Написать программы для консольного процесса Server и консольных процессов Client. Для моделирования передачи сообщений ввести специальные события, которые обозначают любые цифры. Процесс Server:
Процесс Client:
Вариант 10 Написать программы для консольного процесса Server и консольных процессов Client. Для моделирования передачи сообщений ввести специальные события, которые обозначают любые английские буквы. Процесс Server:
Процесс Client:
Вариант 11 Написать программы для консольного процесса Server и консольных процессов Client. Для моделирования передачи сообщений ввести специальные события, которые обозначают любые символы, кроме букв. Процесс Server:
Процесс Client:
Вариант 12 Написать программы для консольного процесса Server и консольных процессов Client. Для моделирования передачи сообщений ввести специальные события, которые обозначают передачу любых символов, кроме букв и цифр. Процесс Server:
Процесс Client:
Вариант 13 Задача о napикмахере. В тихом городке есть парикмахерская. Салон парикмахерской мал.ходить там может только парикмахер и один посетитель. Парикмахер всю жизнь обслуживает посетителей. Когда в салоне никого нет, он спит в кресле. Когда посетитель приходит и видит спящего парикмахера, он будет его, садится в кресло и спит, пока парикмахер занят стрижкой. Если посетитель приходит, а парикмахер занят, то он встает в очередь и засыпает. После стрижки парикмахер сам провожает посетителя. Если есть ожидающие посетители, то парикмахер будит одного из них, и ждет пока тот сядет в кресло парикмахера и начинает стрижку. Если никого нет, он снова садится в свое кресло и засыпает до прихода посетителя. Создать многопоточное приложение, моделирующее рабочий день парикмахерской. Вариант 14 Задача о Винни-Пухе или правильные пчелы. В одном лесу живут n пчел и один медведь, которые используют один горшок меда, вместимостью Н глотков. Сначала горшок пустой. Пока горшок не наполнится, медведь спит. Как только горшок заполняется, медведь просыпается и съедает весь мед, после чего снова засыпает. Каждая пчела многократно собирает по одному глотку меда и кладет его в горшок. Пчела, которая приносит последнюю порцию меда, будит медведя. Создать многопоточное приложение, моделирующее поведение пчел и медведя. Условную синхронизацию потоков выполнить с помощью событий и семафоров.
Вариант 15 Задача об обедающих философах. Пять философов сидят возле круглого стола. Они проводят жизнь, чередуя приемы пищи и размышления. В центре стола находится большое блюдо спагетти. Спагетти длинные и запутанные, философам тяжело управляться с ними, поэтому каждый из них.чтобы сьесть порцию, должен пользоваться двумя вилками. К несчастью, философам дали только пять вилок. Между каждой парой философов лежит одна вилка, поэтому эти высококультурные и предельно вежливые люди договорились, что каждый будет пользоваться только теми вилками, которые лежат рядом с ним (слева и справа). Написать многопоточную программу, моделирующую поведение философов с помощью семафоров. Программа должна избегать фатальной ситуации, в которой все философы голодны, но ни один из них не может взять обе вилки (например, каждый из философов держит по одной вилки и не хочет отдавать ее). Решение должно быть симметричным, то есть все потоки-философы должны выполнять один и тот же код. Вариант 16 Задача о каннибалах. Племя из пдикарей ест вместе из большого горшка, который вмешает т кусков тушеного миссионера. Когда дикарь хочет обедать, он ест из горшка один кусок, если только горшок не пуст, иначе дикарь будит повара и ждет, пока тот не наполнит горшок. Повар, сварив обед, засыпает. Создать многопоточное приложение, моделирующее обед дикарей. При решении задачи пользоваться семафорами. Вариант 17 Задача о курильщиках. Есть три процесса-курильщика и один процесс-посредник. Курильщик непрерывно скручивает сигареты и курит их. Чтобы скрутить сигарету, нужны табак, бумага и спички. У одного процесса-курильщика есть табак, у второго - бумага, а у третьего - спички. Посредник кладет на стол по два разных случайных компонента. Тот процесс-курильщик, у которого есть третий компонент, забирает компоненты со стола, скручивает сигарету и курит. Посредник дожидается, пока курильщик закончит, затем процесс повторяется. Создать многопоточное приложение, моделирующее поведение курильщиков и посредника. Вариант 18 Задача о супермаркете. В супермаркете работают два кассира, покупатели заходят в супермаркет, делают покупки и становятся в очередь к случайному кассиру. Пока очередь пуста, кассир спит, как только появляется покупатель, кассир просыпается. Покупатель спит в очереди, пока не подойдет к кассиру. Создать многопоточное приложение, моделирующее рабочий день супермаркета. Вариант 19 Задача о магазине. В магазине работают три отдела, каждый отдел обслуживает один продавец. Покупатель, зайдя в магазин, делает покупки в произвольных отделах, и если в выбранном отделе продавец не свободен, покупатель становится в очередь и засыпает, пока продавец не освободится. Создать многопоточное приложение, моделирую шее рабочий день магазина. Вариант 20 В больнице два врача принимают пациентов, выслушивают их жалобы и отправляют их или к стоматологу или к хирургу или к терапевту. Стоматолог, хирург и терапевт лечат пациента. Каждый врач может принять только одного пациента за раз. Пациенты стоят в очереди к врачам и никогда их не покидают. Создать многопоточное приложение, моделирующее рабочий день клиники. Вариант 21 Задача о гостинице.В гостинице 10 номеров, клиенты гостиницы снимают номер на одну ночь, если в гостинице нет свободных номеров, клиенты устраиваются на ночлег рядом с гостиницей и ждут, пока любой номер не освободится. Создать многопоточное приложение, моделирующее работу гостиницы. Вариант 22 Задача о гостинице-2 (умные клиенты). В гостинице 3 номера с ценой 200 рублей, 5 номеров с ценой 400 рублей и 2 номера с ценой 600 руб. Клиент, зашедший в гостиницу, обладает некоторой суммой и получает номер по своим финансовым возможностям, если тот свободен. Если среди доступных клиенту номеров нет свободных, клиент уходит искать ночлег в другое место. Создать многопоточное приложение, моделирующее работу гостиницы. Вариант 23 Задача о гостинице - 3 (дамы и джентльмены). В гостинице 8 номеров рассчитаны на одного человека и 7 номеров рассчитаны на двух человек. В гостиницу приходят клиенты дамы и клиенты джентльмены, и конечно они могут провести ночь в номере только с представителем своего пола. Если для клиента не находится подходящего номера, он уходит искать ночлег в другое место. Создать многопоточное приложение, моделирующее работу гостиницы. Теоретические сведения Объекты синхронизации и функции ожидания в Windows Определение. Объектами синхронизации называются объекты ядра, которые могут находиться в одном из двух состояний: сигнальном(signaled) и несигнальном(nonsignaled). Можно выделить три класса объектов синхронизации: К первому классу относятся объекты, которые служат только для решения проблемы синхронизации параллельных потоков. К таким объектам синхронизации в Windows относятся : – мьютекс(mutex); – событие(event); – семафор(semaphore). Ко второму классу относится ожидающий таймер (waitabletimer). К третьему классу относятся объекты, которые переходят в сигнальное состояние по завершении своей работы или при получении некоторого сообщения. Примерами таких объектов синхронизации являются потоки и процессы. Пока эти объекты выполняются, они находятся в несигнальном состоянии. Если выполнение этих объектов заканчивается, то они переходят в сигнальное состояние. Мьютексы в Windows Для решения проблемы взаимного исключения между параллельными потоками, выполняющимися в контексте разных процессов, в операционных системах Windows используется объект ядра мьютекс. Создается мьютекс вызовом функции CreateMutex, которая имеет следующий прототип : HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, // атрибутызащиты BOOL bInitialOwner, // начальныйвладелецмьютекса LPCTSTR lpName // имямьютекса ); ПоказначениепараметраLPSECURITY_ATTRIBUTESбудемустанавливатьвNULL. Это означает, что атрибуты защиты заданы по умолчанию, то есть дескриптор мьютекса не наследуется, и доступ к мьютексу имеют все пользователи. Для того чтобы получить доступ к уже созданному мьютексу, поток может также использовать функцию OpenMutex, которая имеет следующий прототип: HANDLEOpenMutex( DWORDdwDesiredAccess, // доступкмьютексу BOOLbInheritHandle // свойствонаследования LPCTSTRlpName // имямьютекса ); Пример 1. Использование мьютекса для синхронизации потоков. // Несинхронизированные потоки, выполняющиеся в разных процессах #include <windows.h> #include <iostream> using namespace std; int main() { inti, j; for (j = 10; j < 20; j++) { for (i = 0; i< 10; i++) { cout<< j << ' '; cout.flush(); Sleep(5); } cout<<endl; } return 0; } Пример 2. Использование мьютекса для синхронизации процессов. // Несинхронизированные потоки, выполняющиеся в разных процессах #include <windows.h> #include <iostream> using namespace std; int main() { charlpszAppName[] = "D:\\os.exe"; STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); // создаемновыйконсольныйпроцесс if (!CreateProcess(lpszAppName, NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi)) { cout<< "The new process is not created." <<endl; cout<< "Press any key to exit." <<endl; cin.get(); returnGetLastError(); } // выводим на экран строки for (int j = 0; j < 10; j++) { for (inti = 0; i< 10; i++) { cout<< j << ' '; cout.flush(); Sleep(10); } cout<<endl; } // ждем пока дочерний процесс закончит работу WaitForSingleObject(pi.hProcess, INFINITE); // закрываем дескрипторы дочернего процесса в текущем процессе CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return 0; } Пример 3. Синхронизация потоков, выполняющихся в разных процессах, с использованием мьютекса. #include <windows.h> #include <iostream> using namespace std; int main() { HANDLE hMutex; inti, j; // открываеммьютекс hMutex = OpenMutex(SYNCHRONIZE, FALSE, "DemoMutex"); if (hMutex == NULL) { cout<< "Open mutex failed." <<endl; cout<< "Press any key to exit." <<endl; cin.get(); returnGetLastError(); } for (j = 10; j < 20; j++) { // захватываеммьютекс WaitForSingleObject(hMutex, INFINITE); for (i = 0; i< 10; i++) { cout<< j << ' '; cout.flush(); Sleep(5); } cout<<endl; // освобождаеммьютекс ReleaseMutex(hMutex); } // закрываем дескриптор объекта CloseHandle(hMutex); return 0; } События Определение.События – разновидность объектов ядра.Они содержат счетчик числа пользователей(как и все объекты ядра) и две булевы пере - менные: одна сообщает тип данного объекта - события, другая – его со - стояние(свободен или занят). События просто уведомляют об окончании какой - либо операции.Объекты - события бывают двух типов: со сбросом вручную(manual - resetevents) и с автосбросом(auto - resetevents).Первые позволяют возобновлять выполнение сразу нескольких ждущих потоков, вторые – только одного. Объект ядра «событие» создается функцией CreateEvent : HANDLE CreateEvent( PSECURITY_ATTRIBUTES psa, BOOL fManualReset, BOOL fInitialState, PCTSTR pszName); Параметр fManualReset(булева переменная) сообщает системе, какое событие следует создать – со сбросом вручную(TRUE) или с автосбросом(FALSE).Параметр fInitialState определяет начальное состояние события – свободное(TRUE) или занятое(FALSE).После того как система создает объект «событие», CreateEvent возвращает описатель события, специфичный для конкретного процесса. Для событий с автосбросом действует следующее правило.Когда его ожидание потоком успешно завершается, этот объект автоматически сбрасывается в занятое состояние. Пример 4. Синхронизация потоков с использованием объекта ядра «событие». // глобальное описание события со сбросом вручную (в занятом состоянии) HANDLE g_hEvent; int WINAPI WinMain() { // создаем объект "событие со сбросом вручную (взанятомсостоянии) g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // создаем три новых потока HANDLE hThread[3]; DWORD dwThreadTD; hThread[0] = _beginthreadex(NULL, 0, WordCount, NULL, 0, &dwThreadlD); hThread[1] = _beginthreadex(NULL, 0, SpellCheck, NULL, 0, &dwThreadID); hTbread[2] = _beginthreadex(NULL, 0, GrarrmarCheck, NULL, 0, &dwThreadID); OpenFileAndReadContentsIntoMemory(); // разрешаемвсемтремпотокамобращатьсякпамяти SetEvent(g__hEvent), } DWORDWINAPIWordCount(PVOIDpvParam) { // ожиданиезагрузкиданныхизфайлавпамятьWaitForSingleObject(g_hEvent, INFINITE); // обращениекблокупамятиreturn(0); } DWORD WINAPI SpellCheck(PVOID pvParam) { // ожиданиезагрузкиданныхизфайлаWaitForSingleObject(g_hFvent, INFINITE); // обращание к блоку памяти return(0 }; } DWORD WINAPI GrammarCheck(PVOID pvParam) { // ждем, когдавпамятьбудутзагруженыданныеизфайлаWaitForSingleObject(g_hFvent, INFINITE); // обращение к блоку памяти return(0); } При запуске этот процесс создает занятое событие со сбросом вручную и записывает его описатель в глобальную переменную. Пример 5. Использование обьектов - событий для синхронизации задач, принадлежащих различным процессам.Для этого создадим два приложения.Первое приложение СЕРВЕР, запускается первым и его задача заключается в том, чтобы следить за работой второго приложения КЛИЕНТ.Приложение КЛИЕНТ позволяет вводить с помощью клавиатуры и отображать в своем окне произвольные символы.Каждый раз, когда пользователь вводит в окне приложения КЛИЕНТ какой - либо символ, в окне контролирующего приложения СЕРВЕР отображается символ "*". Приложение «КЛИЕНТ» #include<windows.h> #include <stdio.h> #include <conio.h> intmain() { // Открываем событие Start, созданное сервером HANDLE hStart = OpenEvent( EVENT_ALL_ACCESS, // Типдоступаксобытию // (полный доступ) TRUE, START // Имя события ); // Если событие не открылось успешно, то сервер не запущен if (!hStart) { printf("No connection...\n"); return -1; } // Событие Press будет сообщать серверу о нажатии клавиши HANDLE hPress = CreateEvent( NULL, // Атрибуты безопасности (как и у процесса) FALSE, // Ручной сброс, т.е. будет ли событие автоматически // переходить в несигнальное состояние // после удачного вызова // WaitForSingleObject и т.п. // или его надо сбросить вручную // (автоматический сброс) FALSE, // Начальное состояние (несигнальное) PRESS // Имя ); // Событие Show будет сообщать клиенту о печати сервером '*' HANDLE hShow = OpenEvent(EVENT_ALL_ACCESS, TRUE, SHOW); // Событие Work будет сообщать серверу о том, что клиент еще работает // по окончании работы клиент сбрасывает Work в несигнальное состояние // и сервер завершает работу // Событие Work создается без автопереключения (2-й параметр) HANDLE hWork = CreateEvent(NULL, TRUE, TRUE, WORK); // Говорим серверу, что готовы к работе, т.е. // устанавливаем событие Start в сигнальное состояние SetEvent(hStart); // Событие Start нам больше не нужно, закрываем его CloseHandle(hStart); // Цикл считывания нажатия клавиш, пока не нажата кнопка Esc (Code = 27) BYTE ch; while ((ch = LOBYTE(LOWORD(getch()))) != 27) { if (ch == 13) // Нажат Enter (Code = 13) { printf("\n"); } else { printf("%c", ch); } // Говорим серверу, что кнопка нажата SetEvent(hPress); // Ждем пока сервер не отобразит '*' WaitForSingleObject(hShow, INFINITE); } // Сбрасываем (переводим в несигнальное состояние) событие Work // тем самым предлагаем серверу завершить работу ResetEvent(hWork); // В данный момент сервер все еще ждет события Press SetEvent(hPress); // Закрываем созданные и открытые события CloseHandle(hPress); CloseHandle(hShow); CloseHandle(hWork); return 0; } Приложение «СЕРВЕР» #include <windows.h> #include <stdio.h> #include <conio.h> intmain() { // Создаем событие Start в несигнальном состоянии HANDLE hStart = CreateEvent(NULL, FALSE, FALSE, START); // Создаем событие Show, которое будет говорить клиенту о том, что // сервернапечаталсимвол '*' HANDLE hShow = CreateEvent(NULL, FALSE, FALSE, SHOW); // Ожидаем, пока клиент не переведет событие Start в сигнальное состояние, // тем самым подтвердит свою готовность к работе printf("Wait..."); WaitForSingleObject(hStart, INFINITE); printf("\n"); // Открываем события созданные клиентом для синхронизации // Press – кнопка нажата, нужно вывести '*' // Work – пока это событие в сигнальном состоянии // клиент находится на связи, иначе – завершаем работу HANDLE hPress = OpenEvent(EVENT_ALL_ACCESS, TRUE, PRESS); HANDLE hWork = OpenEvent(EVENT_ALL_ACCESS, TRUE, WORK); // Пока клиент на связи, // т.е. событие Work находится в сигнальном состоянии while (WaitForSingleObject(hWork, 0) == WAIT_OBJECT_0) { // Ожидаемнажатиекнопки, отклиента WaitForSingleObject(hPress, INFINITE); printf("*"); // Говорим, чтовывелизвездочкунаэкран SetEvent(hShow); } printf("\nExit\n"); // Закрываемоткрытыесобытия CloseHandle(hStart); CloseHandle(hPress); CloseHandle(hShow); CloseHandle(hWork); return 0; } Семафоры Определение.Семафор – неотрицательная целая переменная, значение которой может изменяться только при помощи неделимых операций. Пример 5. Использование бинарного семафора для моделирования критических секций и событий. semaphor s = 1; // семафорсвободен void thread_1() void thread_2() { { . . . . . . . . . P(s); P(s); if (n % 2 == 0) n++; 28 n = a; V(s); else n = b; V(s); ... } ... ... } Как следует из определения операций над семафором, данный подход решает проблему взаимного исключения одновременного доступа к переменной n для потоков thread_1 и thread_2.Таким образом, бинарный семафор позволяет решить проблему взаимного исключения. Теперь предположим, что поток thread_1 должен производить проверку значения переменной n только после того, как поток thread_2 увеличит значение этой переменной.Для решения этой задачи модифицируем наши программы следующим образом: semaphors = 0; // семафорзанят void thread_1() void thread_2() { { . . . . . . . . . P(s); n++; if (n % 2 == 0) V(s); n = a; else . n = b; ... } ... ... } Как видно из этих программ, бинарный семафор позволяет также ре - шить задачу условной синхронизации. Семафоры в Windows Семафоры в операционных системах Windows описываются объектами ядра Semaphores.Семафор может находиться в двух состояниях: сигнальном(если его значение больше нуля) и несигнальном(если его значение меньше или равно нулю).Создаются семафоры посредством вызова функции CreateSemaphore, которая имеет следующий прототип : HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES lpSemaphoreAttribute, // атрибутыза-щиты LONG lInitialCount, // начальное значение семафора LONG lMaximumCount, // максимальное значение семафора LPCTSTR lpName // имя семафора ); Пример 6. Считающий семафор используется для синхронизации работы потоков.Для этого сначала рассмотрим несинхронизированный вариант этой программы. // Несинхронизированные потоки #include <windows.h> #include <iostream> using namespace std; volatileint a[10]; DWORD WINAPI thread(LPVOID) { inti; for (i = 0; i< 10; i++) { a[i] = i + 1; Sleep(17); } return 0; } int main() { inti; HANDLE hThread; DWORD IDThread; cout<< "An initial state of the array: "; for (i = 0; i< 10; i++) 30 cout<< a[i] << ' '; cout<<endl; // создаем поток, который готовит элементы массива hThread = CreateThread(NULL, 0, thread, NULL, 0, &IDThread); if (hThread == NULL) returnGetLastError(); // поток main выводитэлементымассива cout<< "A modified state of the array: "; for (i = 0; i< 10; i++) { cout<< a[i] << ' '; cout.flush(); Sleep(17); } cout<<endl; CloseHandle(hThread); return 0; } Теперь кратко опишем работу этой программы.Поток thread последовательно присваивает элементам массива «a» значения, которые на единицу больше, чем их индекс. Поток main последовательно выводит элементы массива «a» на консоль.Так как потоки thread и main не синхронизированы, то неизвестно, какое состояние массива на консоль поток main.Наша задача состоит в том, чтобы поток main выводил на консоль элементы массива «a» сразу после их подготовки потоком thread.Для этого мы используем считающий семафор.Следующая программа показывает, как этот считающий семафор используется для синхронизации работы потоков. // Пример синхронизации потоков с использованием семафора #include <windows.h> #include <iostream> using namespace std; volatileint a[10]; HANDLE hSemaphore; DWORD WINAPI thread(LPVOID) { inti; for (i = 0; i< 10; i++) { a[i] = i + 1; // отмечаем, что один элемент готов ReleaseSemaphore(hSemaphore, 1, NULL); Sleep(500); } return 0; } int main() { inti; HANDLE hThread; DWORD IDThread; cout<< "An initial state of the array: "; for (i = 0; i< 10; i++) cout<< a[i] << ' '; cout<<endl; // создаемсемафор hSemaphore = CreateSemaphore(NULL, 0, 10, NULL); if (hSemaphore == NULL) returnGetLastError(); // создаем поток, который готовит элементы массива hThread = CreateThread(NULL, 0, thread, NULL, 0, &IDThread); if (hThread == NULL) returnGetLastError(); // поток main выводит элементы массива // только после их подготовки потоком thread cout<< "A final state of the array: "; for (i = 0; i< 10; i++) { WaitForSingleObject(hSemaphore, INFINITE); cout<< a[i] << ' '; cout.flush(); } cout<<endl; CloseHandle(hSemaphore); CloseHandle(hThread); return 0; } |
||
Последнее изменение этой страницы: 2018-05-29; просмотров: 310. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |