|
Программирование >> Структура ядра и системные вызовы
Идентификатор нового потока возвращается через аргумент tid p. Если этому аргументу присвоено фактическое значение NULL, никакой идентификатор не возвращается. Тип данных идентификатора потока - threadj. Функция thrcreate может не выполниться в тех случаях, когда недоста-точно системной памяти для создания нового потока, когда аргумент stackp содержит неверный адрес или когда значение аргумента stack size не равно нулю и меньше установленного системой минимального предела. Установленный системой минимально допустимый размер стека можно узнать с помощью функции thrminstack: size t thr min stack ( void ); Поток может выяснить свой идентификатор через функцию thrjself. thread t thrjself ( void ); В приведенном ниже примере создается новый отсоединенный и связанный поток для выполнения функции dojt. Аргумент, передаваемый этой функции, представляет собой адрес переменной pint. Идентификатор нового потока присваивается переменной tid\ создается стек стандартного размера: extern void* do it(void* ptr) ; int *plnt; thread t tid; - if {thr create (0, 0, do it, (void*) splnt, THR DETACHEDITHR BOUND, Stid) < 0) perror( thr create ); 13.3.2. Функции thr suspend, thr continue , Прототипы функций thrjsuspend и thr continue выглядят следующим образом: #include <thread.h> int thrjsuspend ( thread t tid ); int Ithrjcontinue ( thread t tid ); Функция ГЛг 5Ы5/>елй? приостанавливает выполнение потока, идентификатор которого обозначен аргументом tid. Функция thrcontinue возобновляет выполнение потока, идентификатор которого обозначен аргументом tid. Если аргумент tid имеет недопустимое значение, эти функции шгут завершиться неудачно. 13.3.3. функции thr exlt, thrjoin Прототипы функций thr exit и thr Join выглядят следующим образом: #lnclude <thread.h> у int thrjexit ( void* statusp ); int thr Join ( thread t tid, thread t* dead tidp, void** statusp ); Функция threxit завершает поток. Фактическим значением аргумента statusp является адрес статической переменной, которая содержит код возврата завершающегося потока. Если ни один из других потоков не будет использовать код возврата завершающегося потока (например, поток отсоединяется), значение этого аргумента можно указать как NULL. Функция thr Join вызывается для ожидания завершения неотсоединенно-го потока. Если аргумент tid равен нулю, функция ожвдает завершения любого потока. Значения аргументов deadjidp и status - адреса переменных, которые содержат идентификатор и код возврата завершенного потока. Если эти данные не нужны, значения аргументов могут быть установлены равными NULL. В приведенном ниже примере программа ждет завершения всех неотсо-сдиненных потоков процесса, а затем завершает текущий поток: status int *rc, rval = 0; thread t tid; while (! thrjoin (0, Stid, &rc) ) cout thread: (int)tid thr exit( (void*)&rval ); exits, rc= (rc*) endl; 13.3.4. Функции thr sigsetmask и thr kill у каждого потока есть сигнальная маска, которую он наследует от создавшего его процесса. Поток может модифицировать свою сигнальную маску, воспользовавшись функцией thrsigsetmask. Когда в многопотоковый процесс поступает какой-то сигнал, его получает поток, в котором этот сигнал не заблокирован. Если сигнал не заблокирован в нескольких потоках, система выбирает в качестве пункта назначения сигнала один из этих потоков. Поэтому для упрощения реализации многопотоковых программ рекомендуется, чтобы процесс выбирал определенный поток для обработки одного и более сигналов, а в остальных потоках этого процесса данные сигналы блокировались. ;/ Кроме того, поток; может посылать сигнал в: другой поток в этом же процессе, пользуясь функцией ihrkill. Прототипы функций thrsielnmk и гг Ш выглядят следующим образом: ; #include <thread.h> Щ #include <signal.h> int thrjsigsetmask { Int mode, sigset t* sigsetp, sigset t* oldsetp ); int thrjdil { thread t tid, Int signum ); Функция thrsigsetmask устанавливает сигнальную маску вызывающего потока. Аргумент sigsetp содержит один или несколько номеров сигналов, применяемых к вызывающем потоку. Аргумент mode показывает, как следует использовать сигнал (сигналы), заданный в аргументе sigsetp. Возможные значения аргумента mode объявляются в заголовке <signal.h>. Значение аргумента made Смысл SIG BLOCK SIG UNBLOCK SIG SETMASK Добавляет сигналы, указанные в аргументе sietp, в сигнальную маску потока Удаляет сигналы, указанные в аргументе sietp, из сигнальной маски потока Заменяет сигнальную маску потока сигналом (или сигналами), указанным в аргументе sigsetp Если аргумент sigsetp имеет значение NULL, значение аргумента mode игнорируется. Значением аргумента oldsetp должен бьггь адрес переменной типа sigsetj*, с помощью которой возвращается старая сигнальная маска. Если значение аргумента oldsetp - NULL, то старая сигнальная маска не возвращается. Функция thr Jill передает сигнал, заданный аргументом signum, в поток, идентификатор которого задан аргументом tid. Передающий и принимающий потоки должны находиться в одном процессе. В приведенном ниже примере программа добавляет сигнал SIGINT в сигнальную маску потока, а затем посылает сигнал SIGTERM в поток с идентификатором 15: sigset set, oldset; i !1 sigemptyset (sset); * t;, sigaddset (sset, SIGINT); ; if (thr setsigraas3c (SIG BLOCK, sset/ Soldset.) ) perror( thr sigsetmask ) ; if (thr kill((thread t\%5, SIGTERM) perror ( thrlkill-y ; 13.3.5. Функции thr setprio, thr getprio и thr yleldr.£r Прототипы функций thrjseprio, thr getprio и thr yield выглядят следующим образом: #include <thread.h> int int void thrjsetpria (thread t tid, Int prio); thr getprid (thread t tid, int* рпорУ- * dirjjield (void); !oqn йи. Функция thr setprio устанаштивает приоритет потока, обозначенного аргументом tid, в значение prio. Потоки с более высокими приоритетами назначаются к вьшолнению чаще, чем потоки с низкими приоритетами. Функция thr getprio возвращает текущее значение приоритета потока через аргумент priop. Этот поток обозначается аргументом tid. Функция thr yield вызывается потоком для передачи выполнения другим потокам с таким же приоритетом. Эта функция всегда вьшолняется успешно и никакого значения не возвращает. Планирование потоков вьшолняется многопотоковыми библиотечными функциями, а не ядром. Потоки планируются ддя связывания с облегченными процессами, которые, в свою очередь, планируются ядром ддя выполнения на аппаратном процессоре. 13.3.6. функции thr setconcurrency и thr getconcuiTency Прототипы функций thr setconcurrency и thrjgetconcurrency выглядят сле-дуййцим образом: #include <thread.h> int thr setcancurrencg (Int amount); int thr getcancurrency (void); Функция thrjsetconcurrency задает минимальное количество облегченных процессов, которые должны существовать в процессе. Таким образом обеспечивается возможность параллельного вьшолнения минимального числа потоков в любой момент времени. Заметим, что система принимает значение аргумента amount как рекомендацию, придерживаясь этого значения настолько, насколько позволяют наличные ресурсы. Функция thr getconcurrency возвращает значение, равное текущему количеству облегченных процессов для процесса. 13.3.7. Пример многопотоковой программы Ф приведенная ниже программа - это измененная версия клиентской и серверной RPC-программ, рассмотренных в разделе 12.5. Программа-клиент получает от пользователя строку сообщения и выполняет RPC-вызов серверной функции printmsg, которая выводит сообщение на системную консоль сервера. Изменения касаются только программы-клиента (msg cls.Q. Клиент многократно запрашивает у пользователя имя хост-сервера и сообщение. Клиентский процесс вызывает функцию, которая для каждого имени хост-машины и данных сообщения, принятого от пользователя, динамически выделяет область памяти. Затем процесс создает поток для передачи RPC-вызова серверу, работающему на указанной хост-машине, и требует, чтобы пользовательское сообщение было выведено на серверную системную консоль. Ниже приведена новая программа-клиент msg cls2.C: /* client program: low-level RPC APIs */ finclude <thread.h> tinclude <signal.h> tinclude msg2.h finclude RPC.h ... t; йМНГ Р,}Г. .Ant extern C int thr sigsetmask(int, const sigset *ljigs,et t ; id a . -ф. fdefine MAX THREAD 200 /* запись для одной хост-машины и данные сообщения для одного потока */ typedef struct char *host; char *msg; ) MSGREC; thread t thread list[MAX THREAD]; содержит идентификаторы всех потоков /* функция, с помощью которой поток передает сообщение */ void* send msg( void* ptr ) int res; MSGREC *pRec (MSGREC*)ptr /* установить сигнальную маску потока в любое значение, кроме SIGHUP */ sigset t setv; sigfillset (ssetv); Sigdelset (ssetv, SIGHUP) ; МЫ if (thr sigsetmask(SlG SETMASK, Ssetv, 0)) perror( thr setsigmask ); /* создать обработчик клиента для связи с хост-машиной */ RPC cls с1( pRec->host, MSGPROG, MSGVER, netpath ); if (icl.goodO) thr exit( Sres ); /* вызвать удаленную хост-машину для вывода сообщения на ее системную консоль */ (void) cl. calK PRINTMSG, (xdrprpc t) xdr string, JijsaddxJO S Rec->lnsg), (xdrproc t)xdr int, (caddr t)Sres); /♦освободить динамически выделяемую память*/ , delete pRec->msg; delete pRec->host; delete pRec; /* проверить статус выполнения RPC-функции */ if (res!=0) cerr clnt: call printmsg falls\rt*; Int *rcp = new int(res); thr exit( rep ); return 0; -нн а /* функция, которая создает поток для пользовательского сообщения */ int add thread( ints num thread ) char host[60], msg(256]; thread t tid; , fnt res; -Ac 7 /* получить от пользователя имя удаленной хост-машины и сообщение */ cin host msg; if (Cin.eofO) return RPC FAILED; /* нормальное завершение */ if (Icin.goodO) ( /* обнаружена ошибка ввода-вывода */ perror( cin ); return RPC FAILED; /* вьщелить память для текста сообщения и имени хост-машины*/ MSGREC *pRec = new MSGREC; pRec->host = new char[strlen(host)+1]; pRec->msg = new char[strlen(msg)+1]; strcpy(pRec->host,host); strcpy(pRec->msg,msg); /* для обработки сообщения создать ожидающий выполнения поток */ iimr (thr create( О, О, send msg, pRec, THR SUSPENDED, Stid )) т,п1.1 perror ( thr create ); return <RPC FAILED; else if (num thread>= MAX THREAD) ( cerr TOO many threads created!\n ; returh RPC FAILED;
else { */* еоЯать поток */- Шш* 1Э. Миогопотоивмм программироааиие
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |