Системное программирование в среде Windows
Шрифт:
for (ithread = 0; ithread < nthread; ithread++) {
WaitForSingleObject(producer_th[ithread], INFINITE);
_tprintf(_T("ХОЗЯИН: производитель %d выработал %d единичных сообщений\n"), ithread, producer_arg[ithread].work_done);
}
/* Производители завершили работу. */
_tprintf(_T("ХОЗЯИН: Все потоки производителя выполнили свою работу.\n"));
/* Ждать завершения потоков
потребителя. */
for (ithread = 0; ithread < nthread; ithread++) {
WaitForSingleObject(consumer_th[ithread], INFINITE);
_tprintf(_T("ХОЗЯИН: потребитель %d принял %d одиночных сообщений\n"), ithread, consumer_arg[ithread].work_done);
}
_tprintf(_T("ХОЗЯИН: Все потоки потребителя выполнили свою работу.\n"));
ShutDown = 1; /* Установить флаг завершения работы. */
/* Завершить выполнение и перейти в состояние ожидания передающих и принимающих потоков. */
/* Эта процедура завершения работает нормально, поскольку и передающий,*/
/* и принимающий потоки не владеют иными ресурсами, кроме мьютекса, */
/* которые они могли бы покинуть по завершении выполнения, не уступив прав владения ими. Можете ли вы улучшить эту процедуру? */
TerminateThread(transmitter_th, 0);
TerminateThread(receiver_th, 0);
WaitForSingleObject(transmitter_th, INFINITE);
WaitForSingleObject(receiver_th, INFINITE);
q_destroy(&p2tq);
q_destroy(&t2rq);
for (ithread = 0; ithread < nthread; ithread++) q_destroy(&r2cq_array [ithread]);
free(r2cq_array);
free(producer_th);
free(consumer_th);
free(producer_arg);
free(consumer_arg);
_tprintf(_T("Система завершила работу. Останов системы\n"));
return 0;
}
DWORD WINAPI producer(PVOID arg) {
THARG * parg;
DWORD ithread, tstatus;
msg_block_t msg;
parg = (THARG *)arg;
ithread = parg->thread_number;
while (parg->work_done < parg->work_goal) {
/* Вырабатывать единичные сообщения, пока их общее количество */
/* не станет равным "goal". */
/* Сообщения снабжаются адресами отправителя и адресата, которые в */
/*
нашем примере одинаковы для всех сообщений, но в общем случае */
/* могут быть различными. */
delay_cpu(DELAY_COUNT * rand / RAND_MAX);
message_fill(&msg, ithread, ithread, parg->work_done);
/* Поместить сообщение в очередь. */
tstatus = q_put(&p2tq, &msg, sizeof(msg), INFINITE);
parg->work_done++;
}
return 0;
}
DWORD WINAPI transmitter(PVOID arg) {
/* Получись несколько сообщений от производителя, объединяя их в одно*/
/* составное сообщение, предназначенное для принимающего потока. */
DWORD tstatus, im;
t2r_msg_t t2r_msg = {0};
msg_block_t p2t_msg;
while (!ShutDown) {
t2r_msg.num_msgs = 0;
/* Упаковать сообщения для передачи принимающему потоку. */
for (im = 0; im < TBLOCK_SIZE; im++) {
tstatus = q_get(&p2tq, &p2t_msg, sizeof(p2t_msg), INFINITE);
if (tstatus != 0) break;
memcpy(&t2r_msg.messages[im], &p2t_msg, sizeof(p2t_msg));
t2r_rasg.num_msgs++;
}
tstatus = q_put(&t2rq, &t2r_msg, sizeof(t2r_msg), INFINITE);
if (tstatus != 0) return tstatus;
}
return 0;
}
DWORD WINAPI receiver(PVOID arg) {
/* Получить составные сообщения от передающего потока; распаковать */
/* их и передать соответствующему потребителю. */
DWORD tstatus, im, ic;
t2r_msg_t t2r_msg;
msg_block_t r2c_msg;
while (!ShutDown) {
tstatus = q_get(&t2rq, &t2r_msg, sizeof(t2r_msg), INFINITE);
if (tstatus != 0) return tstatus;
/* Распределить сообщения между соответствующими потребителями. */
for (im = 0; im < t2r_msg.num_msgs; im++) {
memcpy(&r2c_msg, &t2r_msg.messages[im], sizeof(r2c_msg));
Поделиться:
Популярные книги
Война
7. Ермак
Фантастика:
боевая фантастика
альтернативная история
5.25
рейтинг книги
Экономка тайного советника
Фантастика:
фэнтези
5.00
рейтинг книги
Чужбина
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Мятежник
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга вторая
2. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Метатель. Книга 3
3. Метатель
Фантастика:
попаданцы
альтернативная история
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Студент из прошлого тысячелетия
2. Соприкосновение миров
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Ты не мой BOY
5. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Идеальный мир для Лекаря 2
2. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Лекарь для захватчика
Фантастика:
попаданцы
историческое фэнтези
фэнтези
5.00
рейтинг книги
Отверженный VI: Эльфийский Петербург
6. Отверженный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Он тебя не любит(?)
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Убивать чтобы жить 3
3. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Темный Лекарь 11
11. Темный Лекарь
Фантастика:
попаданцы
аниме
фэнтези
5.00