КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Приостановка и повторный запуск нити
Для нитей существует один вид системного действия, аналогов которому нет для процессов в операционных системах Windows и OS/2. Это – приостановка и повторный запуск отдельной нити. По смыслу действия одна из нитей процесса отдает приказ на приостановку другой нити этого же процесса. Приостановить нить другого процесса программным приказом невозможно (так как в подобном действии при внимательном анализе нет никакого практического смысла). В операционной системе Unix для приостановки отдельной нити можно и нужно использовать уже знакомую читателю функцию pthread_kill со вторым параметром, задаваемым символической константой SIGSTOP, а для возобновления работы нити - ту же функцию, но уже с параметром SIGCONT. Следующий пример, представленный программой в листинге 8.4.1, демонстрирует приостановки и возобновление работы отдельной нити в операционной системе Unix, поддерживающей стандарт POSIX.
#include <pthread.h> #include <stdio.h> #include <signal.h> char lbuk[ ]="abcdefghijklmnoprstuwxyz"; pthread_t tid1, tid2, tid3;
void procthread1(void *arg) {int k, j; for (k=0; k<24; k++) {printf("\033[%02d;20H",k+1); printf("\033[1;34m"); for (j=0; j<(int)arg; j++) printf("%c",lbuk[k]); if (k= =5) {pthread_kill(tid2, SIGSTOP); printf("-Suspend thread2");} if (k= =11) {pthread_kill(tid2, SIGCONT); printf("-Resume thread2");} printf("\n"); usleep(800000); } }
void procthread2(void *arg) {int k, j; for (k=0; k<24; k++) {printf("\033[%02d;40H",k+1); printf("\033[1;32m"); for (j=0; j<(int)arg; j++) printf("%c",lbuk[k]); usleep(1300000); } }
void procthread3(void *arg) {int k, j; for (k=0; k<24; k++) {printf("\033[%02d;60H",k+1); printf("\033[1;31m"); for (j=0; j<(int)arg; j++) printf("%c",lbuk[k]); printf("\n"); usleep(1100000); } }
int main() {int k; int rc;
printf("\033[2J\n"); rc=pthread_create(&tid1, NULL, (void*)procthread1, (void*)2); rc=pthread_create(&tid2, NULL, (void*)procthread2, (void*)3); rc=pthread_create(&tid3, NULL, (void*)procthread3, (void*)4); for (k=0; k<24; k++) {printf("\033[%02d;1H",k+1); printf("\033[1;37m"); printf("%c++",lbuk[k]); printf("\n"); usleep(1000000); } pthread_join(tid1,NULL); pthread_join(tid2,NULL); pthread_join(tid3,NULL); printf("\033[0m"); return 0; } Листинг 8.4.1. Программа с приостановкой нитей для Unix
В этой программе первая нить на 5-м шаге своей работы отдает приказ приостановки второй нити (идентификатор которой в tid2). Второй нитью мы здесь называем нить с идентификатором tid2, работающую на основе процедуры procthread2, а главную нить условно считаем нулевой. Приказ такой приостановки выдается в виде pthread_kill(tid2, SIGSTOP). Сама первая нить после такого приказа продолжает работать, а вторая, как легко наблюдать на экране по выводимым результатам, временно ничего не выводит, будучи приостановленной. Далее на 11-м шаге работы первой нити – в процедуре procthread1 – вызывается функция возобновления работы приостановленной второй нити. Эта функция в программе присутствует в виде pthread_kill(tid2, SIGCONT). После ее выполнения, как можно наблюдать по выводу процесса, который работает по программе из листинга 8.4.1, вторая нить продолжает свой вывод, а следовательно, работает дальше. Небольшие дополнения в программе относительно ее аналога в листинге 8.2.1 осуществляют поясняющий вывод в ходе ее выполнения и предназначены для наглядности наблюдаемого процесса. Программные средства для приостановки и возобновления нитей в операционных системах типа Windows состоят из двух функций ResumeThread и SuspendThread. Обе они имеют единственный аргумент – хэндл нити, на которую они должны подействовать – приостановить или возобновить ее работу. Прототипы этих функций описываются в виде: DWORD SuspendThread(HANDLE hthread); DWORD ResumeThread(HANDLE hthread). Использование этих функций не имеет никаких особенностей в сравнении с другими рассмотренными операционными системами. В листинге 8.4.2 приведены фрагменты программы, отсутствующие части которой должны быть взяты из листинга 8.2.2 (начальная часть, тексты процедур procthread1, procthread2 и опущенные детали остальных). Эта программа создает три нити, кроме главной, и в ходе их работы в одной из них (третьей по условному счету) приостанавливает работу первой из них. Затем через несколько шагов внутреннего цикла в процедуре третьей нити отдается приказ на возобновление работы приостановленной ранее нити.
#include <windows.h> #include <process.h> ...
DWORD WINAPI procthread3(void *arg) {int k, j; COORD pos; for (k=0; k<24; k++) { ... for (j=0; j<(int)arg; j++) printf("%c",lbuk[k]); if (k==5) {SuspendThread(hthread1); pos.X=50; pos.Y=k+1; SetConsoleCursorPosition(hstdout,pos); printf("Suspend thread1 into step=5"); } if (k==16) {ResumeThread(hthread1); pos.X=50; pos.Y=k+1; SetConsoleCursorPosition(hstdout,pos); printf("Resume thread1 into step=16"); } ... Sleep(1000); } }
void main() {unsigned long threadid1, threadid2, threadid3; int k; COORD pos;
hstdout=GetStdHandle(STD_OUTPUT_HANDLE); ... for (k=0; k<24; k++) { ... printf("%c++",lbuk[k]); if (k==9) {TerminateThread(hthread2, 0); pos.X=1; pos.Y=k+1; SetConsoleCursorPosition(hstdout,pos); printf("Kill thread2"); } LeaveCriticalSection(&csec); Sleep(1500); } ... CloseHandle(hthread1); CloseHandle(hthread2); CloseHandle(hthread3); } Листинг 8.4.2. Фрагменты программа с уничтожением нитей для Windows
Заметим, что в программе для управления поведением нитей используются их хэндлы, но никак не используются идентификаторы нитей. Практически в Windows всегда заметна некоторая избыточность средств, которая частично оправдывается большой суммарной сложностью системы.
Дата добавления: 2014-01-05; Просмотров: 432; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |