Родительский процесс, порожденный, «сирота» 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Родительский процесс, порожденный, «сирота»



Права доступа к файлу

У каждого файла есть владелец. Владельцем нового файла становится пользователь, создавший этот файл. Права доступа к файлу определяет его владелец. Права доступа указывают для других пользователей системы, могут ли они читать, изменять и исполнять файл. Права доступа к файлу могут изменяться владельцем файла или пользователем root.

Существует три класса пользователей: пользователь/владелец, пользователи группы и все остальные пользователи. Этим классам пользователей выделяются права доступа трех типов: на чтение, на запись и на выполнение. При создании файла для пользователя, создавшего файл, по умолчанию устанавливаются права на чтение, запись и выполнение. Для остальных двух классов пользователей устанавливаются права на чтение и выполнение. В приведенной ниже таблице описаны права доступа к файлу, выделяемые по умолчанию для трех групп пользователей:

смысл владелец имеет право на группа имеет право на для остальных сохранять в области подкачки образ кодового сегмента n=7,5,3,1 Процесс имеет право изменить свой идентификатор n=6,4,2,0 Разр-ся блокирование диапозонов адресов в файле Устан. идент. польз/владельца при выполнении файла
чтение запись запускать(файл)/просматривать(каталог) чтение запись запускать(файл)/просматривать(каталог) чтение запись запускать(файл)/просматривать(каталог)
ограничение 00400h 00200h 00100h 00040h 00020h 00010h 00004h 00002h 00001h 01000h 020n0h 04000h

 

Родительский процесс, порожденный, «сирота»

Процесс (задача) - программа, находящаяся в режиме выполнения. С каждым процессом связывается его адресное пространство, из которого он может читать и в которое он может писать данные.

Родительский процесс - тот, который порождает процесс.

Порожденный процесс получает копии сегментов текста, данных и стека своего родителя, таблицу дескрипторов файлов с ссылками на открытые файлы.

Ролительский процесс может приостановить свое выполнение до завершения порожденного процесса.

Процесс-сирота — вспомогательный процесс, чей основной процесс (или связь с ним) был завершен нештатно (не подав сигнала на завершение работы). Обычно, «сиротой» остается дочерний процесс после неожиданного завершения родительского.

Проце́сс-зо́мбидочерний процесс завершивший своё выполнение, но ещё присутствующий в списке процессов операционной системы, чтобы дать родительскому процессу считать код завершения.

 

Родитель Потомок main . . fork exec (спит) wait main .. .. . exit exit Родитель Потомок main . . fork exec . main .. . exit (zombie) wait . Exit Родитель Потомок main . . fork exec (спит) wait main .. Exit. (сирота,наслед-ся init) . exit

 

 

Файловая система. Системные вызовы mount, umount.

Любые устройства Unix’ом распознаются как файл. Для Unix файл- это фундаментальная абстракция. Файл-это именованная область. Каждый файл имеет уникальное полное имя. Корень Unix это директория “/”. В файловых системах Unix отсутствует понятие дисков. Расширения в файлах не обязательны. Кроме полных имен существуют относительные имена:

текущий каталог./

родительский отн. текущего../

Родные файловые системы для Unix: ext2,ext3.

mount[какая ФС][куда] – монтировать ФС в точку монтирования

umount[тока монтирования] – изъять ФС в точке монтирования

 

Файловая система. i-nodes.

Любые устройства Unix’ом распознаются как файл. Для Unix файл-это фундаментальная абстракция. Файл-это именованная область. Каждый файл имеет уникальное полное имя. Корень Unix- это директория /. В файловых системах Unix отсутствует понятие дисков. Расширения в файлах не обязательны. Кроме полных имен существуют относительные имена:

текущий каталог./

родительский отн. текущего../

Родные файловые системы для Unix: ext2,ext3.

Блоки в ФС:

1.базовые блоки

2.boot блок(Boot record)

3.superblock – располагается в произв. месте, содержит список свободных блоков и свободных i-nodes.

I-nodes – это перечисление занятых блоков конкретным файлом. В i-nodes содержатся права доступа к файлам, время (созд/мод), имя файла, идентификатор владельца.

Индексный дескриптор, или i-node, содержит информацию о файле, необходимую для обработки данных т.е. метаданные файла. Каждый файл связан, ассоциирован с одним индексным дескриптором, хотя может иметь несколько имен в файловой системе, каждое из которых указывает на один и тот же индексный дескриптор. При открытии файла ядро помещает копию дискового дескриптора в память в соответствующую таблицу (in-core inode), которая содержит несколько дополнительных полей.

 

 

Параметры функции msgget.

функция msgget- для работы с очередью сообщений

Прототип Функции msgget выглядит следующим образом:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/message.h>

int msgget (key_t key, int flag);

Эта функция открывает очередь сообщений, идентификатор которой совпадает со значением аргумента key, и возвращает положительный целочисленный дескриптор. Его можно использовать в других функциях сообщений для передачи и приема сообщений, а также для запроса и/или установки управляющих параметров очереди.

Если значение аргумента key — положительное целое, эта функция пробует открыть очередь сообщений, идентификатор которой совпадает с данным значением. Если же значением key является макрос IPC_PRIVATE, вызов создает новую очередь сообщений, которая будет использоваться исключительно вызывающим процессом.

Если аргумент flag имеет нулевое значение очереди сообщений, идентификатор которой совпадал бы с заданным значением key, то вызов прерывается; в противном случае возвращается дескриптор этой очереди. Если процессу необходимо создать новую очередь (когда нет ни одной очереди), то значение аргумента flag должно содержать макрос IPC_CREAT, а также права на чтение сообщения из новой очереди и запись в неё (для. владельца, группы и прочих).

Если желательно иметь гарантию создания новой очереди сообщений, можно указать одновременно с флагом IPC_CREAT флаг IPC_EXCL, и этот вызов будет успешно выполнен только в том случае, если он создаст новую очередь с заданным значением key.

Параметры функции msgsnd.

Прототип функции msgsnd выглядит следующим образом:
#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgsnd(int msgfd, const void*msgPtr, int len, int flag)

Эта функция передает сообщение (на которое указывает msgPtr) в очередь, обозначенную дескриптором msgfd.

Значение msgfd определяется возвращаемым значащем функции msgget.

Фактическое значение аргумента msgPtr — указателе на объект, который содержит реальный текст и тип сообщения, подлежащего передаче

Значение аргумента 1еn —это размер (в байтах поля mtext объекта, на который указывает аргумент msgPtr.

Аргумент flag может иметь значение 0. Это означает, что при необходимости процесс можно блокировать до тех пор, пока данная функция не будет успешно выполнена. Бела этот аргумент имеет значение IPC_NOWAIT, то при блокировании процесса выполнение функция прерывается. В случае успешного выполнения возвращается 0, а в случае неудачи -1.

Параметры функции msgrcv.

Прототип функции msgrcv выглядит так:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgrcv (int msgfd, const void* msgPtr, int len, int mtype, int flag);

Эта функция принимает сообщение типа mtype из очереди сообщений, обозначенной дескриптором msgfd. Полученное сообщение хранится в объекте, на который указывает аргумент msgPtr. Значение аргумента len — это максимальный размер (в байтах) текста сообшения, которое может быть принято данным вызовом.

Значение msgfd берется из вызова функции msgget

Фактическое значение аргумента msgPtr - указатель на объект, имеющий структуру данных, похожую на struct msgbuf.

Значение mtype.— это тип сообщения, подлежащего приему. Ниже перечислены возможные значения данного аргумента и их смысл.

Значение mtype

Положительное целое Принять самое старое сообщение указанного типа

Отрицательное целое Принять сообщение, тип которого меньше абсолютного значения, mtype или равен ему

Если таких сообщение в очереди несколько, принять то, которое является самым старым и имеет наименьшее значение типа

Аргумент flag может иметь значение 0. Это означает, что провесе можно блокировать, если ни одно сообщение в очереди не удовлетворяет критериям выбора, заданным аргументом mtype. Если в очереди есть сообщение, которое удовлетворяет этим критериям, но превышает величину len, то функция возвращает код неудачного завершения.

Если процесс указал в аргументе flag значение IPC_NOWAIT, то вызов будет неблокирующим. Кроме того, если в названном аргументе установлен флаг MSG_NOERROR, то сообщение, находящееся в очереди, можно читать (даже если его размер превышает len байтов). Функция возвращает вызывающему процессу первые 1еи байтов текста сообщения, а остальные данные отбрасывает.

Функция msgrcv возвращает количество байтов объекта, на который указывает аргумент msgPtr, или -1 (в случае неудачи).

Значение cmd Смысл
IPC_STAT Копировать управляющие параметры очереди в объект, указанный аргументом mbufPtr
IPC_SET Заменить управляющие параметры очереди параметрами, содержащимися в объекте, на который указывает аргумент mbufPtr. Чтобы выполнить эту операцию, вызывающий процесс должен иметь права либо привилегированного пользователя, либо создателя или назначенного владельца очереди. С помощью этого вызова можно устанавливать UID владельца очереди и идентификатор его группы, права доступа и (или) уменьшать лимит msg_qhyte очереди
IPC_RMID Удалить очередь из системы. Чтобы выполнить эту операцию, вызывающий процесс должен иметь права либо привилегированного пользователя, либо создателя или назначенного владельца очереди

Параметры функции msgctl.

С помощью этой функций можно запрашивать управляющие параметры очереди сообщений, обозначенной аргументом msgfd, изменять информацию в управляющих параметрах очереди, удалять очередь из системы.

Значение аргумента msgfd берется из вызова функции msgget.

Ниже перечислены возможные значения аргумента cmd и их смысл.

В случае успешного выполнения возвращается 0, в случае неудачи -1.

 

 

Параметры функции semget.

Прототип функции semget имеет следующий вид:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

int semget (key_t key, int пит_sem, int flag);

Эта функция "открывает" набор семафоров, идентификатор которого задан значением аргумента key, и возвращает неотрицательный целочисленный дескриптор. Его можно использовать в других вызовах семафоров для запроса я

изменения значения семафора, а также для запроса и/или установки управляющих параметров набора семафоров.

Если значение аргумента key — положительное целое, рассматриваемый вызов пробует открыта набор семафоров, ключевой идентификатор которого совпадает с указанным значением. Если же значением key является макрос IPC_PRIVATE, вызов создает новый набор семафоров, который будет использоваться исключительно вызывающим процессом. Такие "частные" семафоры обычно выделяются родительским процессом, создающим затем один или несколько порожденных процессов. Родительский и порожденные процессы пользуются этими семафорами для синхронизации своей работы.

При нулевом значений аргумента flag вызов прерывает свою работу, если отсутствует набор семафоров, ключевой идентификатор которого совпадал бы с заданным значением key; в противном случае возвращается дескриптор этого

набора. Если процессу необходимо создать новый набор с идентификатором key (и набора с таким идентификатором нет), то значение аргумента flag должно представлять собой результат побитового логического сложения константы

IРС_СREAT и числовых значений прав доступа к новому набору для чтения и записи.

Значение num_sem может быть равно нулю, если флаг IPC_CREAT в аргументе flag не указан, или числу семафоров во вновь создаваемом наборе.

Для гарантированного создания нового набора семафоров можно указать одновременно с флагом IPC_CREAT флаг IPC_EXCL. Тогда вызов будет успешно выполнен только в том случае, если он создаст новый набор с заданным значением

В случае неудачи этот вызов возвращает -1.

Параметры функции semop.

Прототип функции semop имеет следующий вид:

#include<sys/types.h>
#include<sys/ipc.h>
#inciude<sys/sem.h>
int semop (int semfd,struc sembuf* opPtr, int len);

С помощью этой функции можно изменять значение одного или нескольких семафоров в наборе (указанном аргументом semfd) и/или проверять равенство их значений нулю. Аргумент opPtr — это указатель на массив объектов типа struct sembuf, каждый из которых задает одну операцию (запрос или изменение значения). Аргумент len показывает, сколько элементов имеется в массиве, указанном аргументом opPtr.

Тип данных struct sembuf определяется в заголовке <sys/sem.h>: struct sembuf{

short sem_num;//индекссемафора short sem_op; // операция над семафором short sem_flg; //флаг(и) операции };

Переменная sem_op может иметь следующие значения.

Для работы с семафорами определены следующие функции: semget, semop и semctl.

Если вызов semop попытается уменьшить значение семафора до отрицательного числа или посчитает, что значение семафора равно нулю, когда на самом деле это не так, то ядро заблокирует вызывающий процесс. Этого не произойдет в том случае, если в полях sem_flg элементов массива, где semop меньше или равно нулю, указан флаг IPC NOWAIT.

В случае успешного выполнения этот вызов возвращает нуль, а в случае
неудачи -1.

 

 

Параметры функции semctl.

Прототип функции semctl имеет следующий вид:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

int semctl(int semfd, int num, int cmd, union semun arg);

С помощью этой функции можно запрашивать и изменять управляющие параметры набора семафоров, указанного аргументом semfd, а также удалять семафор.

Значение semfd — это дескриптор набора семафоров, который берется из вызова функции semget.

Значение num — это индекс семафора, а следующий аргумент, cmd, задает операцию, которая должна быть выполнена над конкретным семафором данного набора.

Аргумент arg — это объект типа union, который может использоваться для задания или выборки управляющих параметров одного или нескольких семафоров набора в соответствии с аргументом cmd. Тип данных union semun
определяется в заголовке <sys/sem.h>

union semun{

int val; //значение семафора

struct semid_ds *buf; //управляющие параметры набора

ushori *array{ // массив значении семафоров

IPC_STAT Копировать управляющие параметры набора в объект, указанный аргументом arg_buf. У вызывающего процесса должно быть право на чтение набора

IPC SET Заменить управляющие параметры набора семафоров данными, определенными в объекте, на который указывает аргумент arg.buf. Чтобы выполнить эту операцию, вызывающий процесс должен иметь права привилегированного пользователя, создателя или назначенного владельца набора. Этот вызов может устанавливать U1D владельца набора и идентификатор его группы, а также права доступа

IPC RMID Удалить семафор из системы. Чтобы выполнить эту операцию, вызывающий процесс должен иметь права привилегированного пользователя, создателя или назначенного владельца набора

GETALL Скопировать все значения семафоров в массив, на который указывает arg.array

SETALL Установить все значения семафоров равными значениям, содержащимся в массиве, на который указывает arg.anay

GETVAL Возвратить значение семафора с номером num. Аргумент arg не используется

SETVAL Установить значение семафора с номером num, равным значению, указанному в arg.val

GETPID Возвратить идентификатор процесса, который выполнял операции над семафором с номером num последним. Аргумент arg не используется.

GETNCNT Возвратить количество процессов, которые в текущий момент заблокированы и ожидают увеличения значения семафора с номером num. Аргумент arg не используется

GETZCNT Возвратить количество процессов, которые в текущий момент заблокированы и ожидают обращения значения семафора с номером num в нуль. Аргумент arg не используется.

В случае успешного выполнения этот вызов возвращает значение, соответствующее конкретному cmd, а в случае неудачи — -1.

 

Параметры функции shmget.

Прототип функции shmget имеет следующий вид:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

int shmget (key_t key, int size, int flag);

Эта функция открывает разделяемую область памяти, идентификатор совпадает со значением аргумента key, и возвращает неотрицательный целочисленный дескриптор. Его можно использовать в других вызовах разделяемой памяти.

Если значение аргумента key —■ положительное целое, данный вызов пробует открыть разделяемую область памяти, ключевой идентификатор которой с этим значением. Если же значением key является макрос IPC_PRIVATE, вызов выделяет новую разделяемую область памяти, которая будет использоваться исключительно выбивающим процессом. Такая "частная" разделяемая область памяти обычно выделяется родительским процессом, который затем создает один или несколько порожденных процессов. Родительский и порожденные процессы пользуются этой разделяемой памятью для обмена данными.

Аргумент size задает размер области разделяемой памяти, которая может быть подсоединена к вызывающему процессу с помощью вызова shmat. Если в результате этого вызова создается новая область разделяемой памяти, ее размер

будет определяться аргументом size. В случае, когда вызов открывает – уже существующую область, значение аргумента size может быть меньше размера выделенной области разделяемой памяти иди равно ему: Если в последнем случае значение size меньше фактического- размера области разделяемой памяти, то вызывающий процесс может получить доступ только к первым size байтам области разделяемой памяти.

Если аргумент flag равен нулю и нет области разделяемой памяти, идентификатор которой совпадал бы с заданным значением key, то этот вызов завершается неудачно. В противном случае он возвращает дескриптор этой

области. Если процессу необходимо создать разделяемую область памяти с заданным key (и области с таким идентификатором нету, то значение аргумента flag и должно представлять собой результат побитового логического сложения константы IPC_CREAT и прав доступа к новой области памяти дня чтения и записи.

В случае успешного выполнения эта функция возвращает положительный дескриптор, а в случае неудачи -1.

 

Параметры функции shmat.

Прототип функции shmat выглядит следующем образом:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

void* shmat (int shmid, void* addr, int flag);

Эта функция подсоединяет область разделяемой памяти, указанную

аргументом shmid, к виртуальному адресному пространству вызывающего процесса. Процесс может затем читать данные из указанной области памяти я записывать в нее данные. Если это вновь создаваемая область разделяемой памяти, то ядро реально выделяет область памяти только тогда, когда первый процесс вызывает рассматриваемую функцию для подсоединения к новой области.

Аргумент addr задает начальный виртуальный адрес адресного.

пространства вызывающего процесса, в которое необходимо отобразить разделяемую память. Если это значение равно нулю, ядро может само найти в вызывающем процессе подходящий виртуальный адрес для отображения разделяемой памяти. Большинство приложений должны устанавливать значение addr в нуль, если они явно не хранят в разделяемой области памяти ссылки на указатели или адреса (например, не держат в этой области связный список). Очень важно, чтобы каждый процесс, обращающийся к данной области памяти, указывал один и тот же начальный виртуальный адрес области, в которую отображена разделяемая память.

Если значение аргумента addr не равно нулю, аргумент flag может содержать флаг SHM_RND. Этот флаг указывает ядру на то, что виртуальный адрес, заданный в аргументе addr, можно округлить до границы страницы памяти. Если флаг SHM_RND отсутствует В значение аргумента addr не равно нулю, соответствующий вызов завершается неудачно.

Аргумент flag может иметь также значение SHM_RDONLY, которое говорит о том, что вызывающий процесс подсоединяется к разделяемой памяти только для чтения. Если этот флаг не установлен, то по умолчанию процесс может читать и записывать данные в разделяемую память с учетом разрешений, установленных создателем данной области.

Этот вызов возвращает виртуальный адрес области отображения

разделяемой памяти, а в случае неудачи -1. Следует отметить, что любой

процесс, с целью подсоединения одной разделяемой, области памяти к

виртуальным адресным пространствам многих процессов, может вызывать функцию shmat многократно.

 

Параметры функции shmdt.

Прототип функции shmdt имеет следующий вид:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

int shmdt (void* addr);

Эта функция отсоединяет разделяемую память от заданного аргументом addr виртуального адреса вызывающего процесса.

Прежде чем вызывать данную функцию, необходимо получить посредством вызова shmat значение addr.

В случае успешного выполнения рассматриваемая функция возвращает 0, а в случае неудачи -1.

 

Параметры функции shmctl.

Прототип функции shmctl имеет следующий вид.

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

int shmctl (int shmid, int and, struct shmid_ds* buf);

С помощью этой функции можно запрашивать управляющие параметры. разделяемой области памяти, указанной аргументом shmid, изменять эти параметры и удалять данную область памяти.

Значение shmid — это дескриптор' разделяемой области памяти, полученный посредством вызова функции shmget.

Аргумент buf — это адрес объекта типа struct shmid_ds, который можно использовать для задания и выборки управляющих параметров разделяемой памяти, указанных аргументом cmd. Ниже перечислены возможные значения аргумента cmd и вызываемые ими действия:

Значение cmd Что должен сделать процесс копировать управляющие параметры разделяемой области памяти в объект, указанный аргументом bnf

IPC SET Заменить управляющие параметры разделяемой области памяти параметрами, определенными в объекте, на который указывает аргумент buf. Чтобы выполнить эту операцию, вызывающий процесс должен иметь права привилегированного пользователя, создателя или назначенного владельца разделяемой памяти.

IPC_STAT Рассматриваемый вызов может устанавливать только UID владельца области и идентификатор его группы, а также права доступа

IPC_RMID Удалить разделяемую область памяти из системы. Чтобы выполнить эту операцию, вызывающий процесс должен иметь права привилегированного пользователя, создателя или назначенного владельца области. Если к разделяемой области памяти, подлежащей удалению, подсоединены один или несколько процессов, то операция удаления будет отложена до тех пор, пока эти процессы не отсоединятся от нее

SHM_LOCK Блокировать разделяемую, область памяти. Для выполнения этой операции вызывающий процесс должен обладать правами привилегированного пользователя

SHM_UNLOCK Разблокировать разделяемую область памяти. Для выполнения этой операции вызывающий процесс должен обладать правами привилегированного пользователя

В случае успешного выполнения рассматриваемый вызов возвращает 0, а в случае неудачи -1.

 

Потоки стандарта Posix.1c

Поток состоит из следующих элементов:

• идентификатора потока;

• динамического стека;

• набора регистров (счетчик команд, указатель стека);

• сигнальной маски;

• значения приоритета;

• специальной памяти.

Поток выполнения создается функцией pthread_create. Каждому потоку присваивается идентификатор, уникальный среди всех потоков процесса. Вновь созданный поток наследует сигнальную маску процесса, динамический стек, значение приоритета и набор регистров. Динамический стек и регистры (счетчик команд и указатель стека) позволяют потоку выполняться независимо от других потоков. Поток может изменить унаследованную сигнальную маску и выделить динамическую память для хранения своих данных.

Потоку при создании назначается соответствующая функция. Поток завершается, когда эта назначенная функция возвращает результат или когда поток вызывает функцию pthread_exit. Когда в процессе создается первый поток, то фактически создаются два потока: один - для выполнения указанной функции, а другой - для продолжения выполнения процесса. Последний поток завершается, когда функция main возвращает результат или он сам вызывает функцию pthread_exit.

Все потоки в процессе совместно используют одни сегменты данных и кода. Когда один поток записывает данные в глобальные переменные в процессе, остальные потоки сразу же видят эти изменения. Если какой-либо поток вызывает функцию exit или exec, то завершаются все потоки и сам процесс. Поэтому завершающийся поток, если он не хочет разрушить процесс, в котором выполняется, должен вызывать функцию pthread_exit.

Поток может изменить свою сигнальную маску с помощью функции pthread_sigmask. Сигнал, передаваемый процессу, получат все потоки, которые не замаскировали его. Поток может посылать сигналы в другие потоки этого же процесса, используя функцию pthread_kill, но не может посылать сигналы в потоки другого процесса, так как уникальность идентификаторов потоков не распространяется на другие процессы.

Потоку присваивается целочисленное значение приоритета. Чем больше это значение, тем чаще планируемое выполнение потока. Значение приоритета потока можно запросить с помощью функции pthread_attr_getschedparam и изменить с помощью функции pthread_attr_setschedparam. Поток может намеренно передать выполнение другим потокам с таким же приоритетом; для этого используется функция sched_yield. Кроме того, поток может ожидать завершения другого потока и получить его код возврата с помощью функции pthread_join.

Потоки бывают присоединяемые (joinable) и отсоединенные (detached). Различия между ними заключаются в управлении ресурсами по завершению потока. Присоединяемый поток после своего завершения не освобождает память до вызова pthread_join, который освобождает всю занимаемую память (стек и т.п.) и возвращает результат выполнения потока. Отсоединенный поток этого не требует – все ресурсы возвращаются системе непосредственно по его завершению, узнать результат в таком случае невозможно ввиду того, что нет переменной, в которую этот результат может быть сохранен.

 

27) Системный вызов pthread_create.

#include <pthread.h>

int pthread_create(pthread_t * thread, pthread_attr_t *attr, void* (*start_routine)(void*), void * arg);

Эта функция создаёт новый поток для выполнения функции, адрес которой задан аргументом start_routine. Функция указанная в этом аргументе должна принимать один входной параметр типа void* и возвращать данные такого же типа. Фактический аргумент, который передается в start_routine функцию в начале выполнения нового потока, указывается в аргументе arg.

Идентификатор нового потока возвращается через аргумент thread. Если этому аргументу присвоено значение NULL, идентификатор не возвращается. Аргумент attr содержит атрибуты, присваиваемые вновь создаваемому потоку. Значение этого аргумента может быть равно NULL, если новый поток должен использовать атрибуты по умолчанию, или адресу объекта содержащего атрибуты. В POSIX.1c определяется набор API для создания, удаления, запроса и установки атрибутов потоков – это функции семейства pthread_attr_init. Объект, содержащий атрибуты, может быть связан с несколькими потоками, чтобы при каждом обновлении атрибутов сделанные изменения распространялись на все потоки, связанные с этим объектом.

 

28)Системные вызовы pthread_self,exit и sched_yield

#include <pthread.h>

pthread_t pthread_self(void);

Возвращает идентификатор потока самому потоку.

#include <pthread.h>

void pthread_exit(void *retval);

Завершает поток. Значение аргумента retval – адрес статической переменной, которая содержит код возврата завершаемого потока. Если никакой другой поток не будет использовать код завершающегося потока, значение переменной retval можно указать как NULL.

#include <sched.h>

int sched_yield(void);

Поток вызывает функцию sched_yield, чтобы передать выполнение другим потокам с таким же приоритетом. При успешном выполнении данная функция возвращает 0, а в случае неудачи –1.

 

29) Системные вызовы pthread_join kill

#include <pthread.h>

int pthread_join(pthread_t th, void **thr_return)

Вызывается для ожидания завершения потока. Возвращает код возврата потока, переданный через вызов функции pthread_exit.

 

#include <pthread.h>

int pthread_kill(pthread_t thread, int signo);

Посылает сигнал, заданный аргументом signo, в поток, идентификатор которого задан аргументом thread. Передающий и принимающий потоки должны находиться в одном процессе.

 

Взаимоисключающие блокировки. Пример тупиковой ситуации.

Взаимоисключающие блокировки (mutex – сокращение от MUTual EXclusion) позволяют организовать выполнение потоков так, что когда несколько потоков пытаются установить такую блокировку, успеха достигает только один из них, который и продолжает выполняться. Остальные потоки блокируются до тех пор, пока эта блокировка не будет снята потоком владельцем. При снятии взаимоисключающие блокировки невозможно предсказать, какой ожидающий поток будет следующим владельцем блокировки.

При использовании взаимоисключающих блокировок следует избегать создания тупиковых ситуаций. Такая ситуация может возникнуть, когда процесс использует несколько взаимоисключающих блокировок и два или более потоков в этом процессе пытаются стать владельцами этих блокировок в произвольной последовательности. Пусть, например, в процессе инициализированы две взаимоисключающие блокировки (А и В), которыми пользуются два потока (X и Y). Допустим, поток X установил блокировку А, а поток Y - блокировку В. Когда X пытается стать владельцем блокировки В, он блокируется, потому что эта блокировка установлена потоком Y. Если затем поток Y пытается стать владельцем блокировки А, он тоже блокируется. Таким образом создается тупиковая ситуация: блокируются оба потока, потому что каждый из них пытается установить блокировку, принадлежащую другому потоку. Ни один из этих потоков не будет выполняться, потому что владелец блокировки заблокирован и не может снять ее.

На первый взгляд использование функции pthread_trywait вместо pthread_wait исключает тупиковую ситуацию, но это не так. В самом деле простая замена pthread_wait на pthread_trywait, приводит к тому, что логика обоих потоков выполняться все равно не будет, хотя потоки и не заблокированы. Это ситуация даже хуже, чем deadlock, т.к. потоки впустую растрачивают ресурсы процессора. Общая рекомендация в подобных случаях – избегать вложения взаимоисключающих блокировок друг в друга.

 

 

31)mutex_init

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

Инициализация взаимоисключающей блокировки. Переменная mutex типа pthread_mutex_t определяется вызывающим потоком. Аргумент mutexattr типа pthread_mutexattr_t – это указатель на объект, содержащий атрибуты для новой блокировки, если эта блокировка должна иметь атрибуты по умолчанию, то значение аргумента mutexattr равно нулю. Функции семейства pthread_mutexattr_init предназначены для создания, удаления, установки и запроса атрибутов мьютексов.

Вместо функции pthread_mutex_init можно использовать статические инициализаторы:

static pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;

static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

static pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;

Указанные макросы fast (быстрый), recursive (рекурсивный) и error check (контроль ошибок) изменяют поведение мьютексовых функций в случае deadlock – тупиковых ситуаций. В справочной системе (man – страницах) имеется подробное описание макросов recursive и error check. В большинстве случаев используются «быстрые» мьютексы, их поведение рассматривается далее.

 

32)mutex_lock mutex_destroy

#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex);

Захват взаимоисключающей блокировки. Если мьютекс уже захвачен, то поток блокируется до его освобождения.

#include <pthread.h>

int pthread_mutex_destroy(pthread_mutex_t *mutex);

Удаление объекта – взаимоисключающая блокировка.

Все перечисленные функции возвращают 0 в качестве успешного завершения, либо не нулевой код ошибки.

 

33)mutex_trylock mutex_unlock

#include <pthread.h>

int pthread_mutex_trylock(pthread_mutex_t *mutex);

Не блокирующий захват взаимоисключающей блокировки. Если мьютекс уже захвачен, то функция pthread_mutex_trylock возвращает код ошибки EBUSY, не блокируя поток.

 

#include <pthread.h>

int pthread_mutex_unlock(pthread_mutex_t *mutex);

Освобождение взаимоисключающей блокировки.

 

Условные переменные

Условные переменные используются для того, чтобы заблокировать потоки до выполнения определенных условий. Условные переменные обычно применяются в сочетании с взаимоисключающими блокировками, чтобы несколько потоков могли ожидать момента выполнения одного условия. Это можно сделать следующим образом. Сначала поток устанавливает взаимоисключающую блокировку, но и сам блокируется до момента выполнения определенного условия. На то время, пока поток заблокирован, установленная им блокировка автоматически снимается. Когда другой поток выполняет поставленное условие, он дает условной переменной сигнал о разблокировании первого потока. После разблокирования потока взаимоисключающая блокировка автоматически вновь устанавливается, и первый поток повторно проверяет условие. Если оно не выполняется, поток опять блокируется условной переменной. Если же условие выполняется, поток снимает взаимоисключающую блокировку и выполняется дальше.

 

 

35) Системные вызовы pthread_cond_init, pthread_cond_signal и pthread_cond_timedwait. Их предназначение и параметры.

int pthread_cond_init(pthread_cond_t *cond,

pthread_condattr_t *cond_attr);

Инициализирует условную переменную.

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);

Блокирует поток на условной переменной, на определенное время.

int pthread_cond_signal(pthread_cond_t *cond);

Разблокирует поток, ожидающий условную переменную.

36) Системные вызовы pthread_cond_broadcast, pthread_cond_wait и pthread_cond_destroy. Их предназначение и параметры.

int pthread_cond_wait(pthread_cond_t *cond,

pthread_mutex_t *mutex);

Блокирует поток на условной переменной.

int pthread_cond_broadcast(pthread_cond_t *cond);

Разблокирует все потоки, ожидающие условную переменную.

 

int pthread_cond_destroy(pthread_cond_t *cond);

Удаление объекта – условная переменная.

 

37) Семафоры POSIX.1b отличаются следующим:

• Семафоры POSIX.1b обозначаются путевым UNUX - именем (если создаются с помощью sem_open), либо остаются безымянными (но с присвоением начального виртуального адреса, если они создаются посредством вызова функции sem_init).

• В POSIX.1b с каждым вызовом sem_open и sem_init создается один семафор, а не набор семафоров.

• Значение семафора POSIX.1b увеличивается и уменьшается на единицу с каждым вызовом sem_post и sem_wait соответственно.

 

38)Системный вызов sem_open. Его предназначение и параметры.

sem_t sem_open(char*name, int flags, mode_t mode,

unsigned int value);

Функция sem_open создает семафор, имя которого задано аргументом name. Значение name должно быть строкой символов, похожей на путевое UNUX – имя, и всегда начинаться с символа «/». Кроме того, не следует ожидать, что будет создан файл с таким именем. Значение аргумента flags может быть равно нулю, если функции известно, что указанный семафор уже существует. Флаг O_CREAT показывает, что следует создать сем



Поделиться:


Последнее изменение этой страницы: 2017-02-06; просмотров: 423; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.227.239.9 (0.231 с.)