Пам'ять, що розділяється і системні виклики fork(), exec() і функція exit()



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


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



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


ЗНАЕТЕ ЛИ ВЫ?

Пам'ять, що розділяється і системні виклики fork(), exec() і функція exit()



Важливим питанням є поведінка сегментів пам'яті, що розділяється, при виконанні процесом системних викликів fork(), exec() і функції exit().

При виконанні системного виклику fork() всі області пам'яті, що розділяється, розміщені в адресному просторі процесу, успадковуються породженим процесом.

При виконанні системних викликів exec() і функції exit() всі області пам'яті, що розділяється, розміщені в адресному просторі процесу, виключаються з його адресного простору, але продовжують існувати в операційній системі.

Поняття про нитку виконання (thread) в UNIX. Ідентифікатор нитки виконання. Функція pthread_self()

На лекції 4 ми говорили, що в багатьох сучасних операційних системах існує розширена реалізація поняття процес, коли процес є сукупністю виділених йому ресурсів і набору ниток виконання. Нитки процесу розділяють його програмний код, глобальні змінні і системні ресурси, але кожна нитка має власний програмний лічильник, свій вміст регістрів і свій стек. Оскільки глобальні змінні у ниток виконання є загальними, вони можуть використовувати їх, як елементи пам'яті, що розділяється, не вдаючись до механізму, описаного вище.

На жаль, операційна система Linux не повністю підтримує нитки виконання на рівні ядра системи. При створенні нового thread'а запускається новий традиційний процес, що розділяє з батьківським традиційним процесом його ресурси, програмний код і дані, розташовані зовні стека, тобто фактично дійсно створюється новий thread, але ядро не уміє визначати, що ці thread'ы є складовими частинами одного цілого. Це "знає" тільки спеціальний процес-координатор, що працює на призначеному для користувача рівні і стартуючий при першому виклику функцій, що забезпечують POSIX інтерфейс для ниток виконання. Тому ми зможемо спостерігати не всі переваги використовування ниток виконання (зокрема, прискорити рішення задачі на однопроцесорній машині з їх допомогою навряд чи вийде), але навіть в цьому випадку thread'и можна задіювати як дуже зручний спосіб для створення процесів із загальними ресурсами, програмним кодом і пам'яттю, що розділяється.

Кожна нитка виконання, як і процес, має в системі унікальний номер – ідентифікатор thread'a. Оскільки традиційний процес в концепції ниток виконання потрактує як процес, що містить єдину нитку виконання, ми можемо взнати ідентифікатор цієї нитки і для будь-якого звичайного процесу. Для цього використовується функція pthread_self(). Нитку виконання, створювану при народженні нового процесу, прийнято називатипочатковою абоголовною ниткою виконання цього процесу.

Функція pthread_self()

#include <pthread.h>pthread_t pthread_self(void);

Опис функції

Функція pthread_self повертає ідентифікатор поточної нитки виконання.

Тип даних pthread_t є синонімом для одного з цілочисельних типів мови З.

Створення і завершення thread'а. Функції pthread_create(), pthread_exit(), pthread_join()

Нитки виконання, як і традиційні процеси, можуть породжувати нитки-нащадки, правда, тільки усередині свого процесу. Кожний майбутній thread усередині програми повинен бути функцією з прототипом

void *thread(void *arg);

Параметр arg передається цій функції при створенні thread'a і може, до деякої міри, розглядатися як аналог параметрів функції main(). Значення, що повертається функцією, може інтерпретуватися як аналог інформації, яку батьківський процес може одержати після завершення процесу-дитини. Для створення нової нитки виконання застосовується функція pthread_create().

Функція для створення нитки виконання

#include <pthread.h>int pthread_create(pthread_t *thread pthread_attr_t *attr void * (*start_routine)(void *) void *arg);

Опис функції

Функція pthread_create служить для створення нової нитки виконання (thread'а) всередині поточного процесу. Справжній опис не є повним описом функції, а служить тільки цілям даного курсу. Для вивчення повного опису звертайтеся до UNIX Manual.

Новий thread виконуватиме функцію start_routine з прототипом

void *start_routine(void *)

передаючи їй як аргумент параметр arg. Якщо вимагається передати більше одного параметра, вони збираються в структуру, і передається адреса цієї структури. Значення, що повертається функцією start_routine не повинне указувати на динамічний об'єкт даного thread'а.

Параметр attr служить для завдання різних атрибутів створюваного thread'а. Їх опис виходить за рамки нашого курсу, і ми завжди вважатимемо їх заданими за умовчанням, підставляючи як аргумент значення NULL.

Значення, що повертаються

При вдалому завершенні функція повертає значення 0 і поміщає ідентифікатор нової нитки виконання за адресою, на яку указує параметр thread. У разі помилки повертається позитивне значення (а не негативне, як в більшості системних викликів і функцій!), яке визначає код помилки, описаний у файлі <errno.h>. Значення системної змінної errno при цьому не встановлюється.

Ми не розглядатимемо її в повному об'ємі, оскільки детальне вивчення програмування з використанням thread'ов не є метою даного курсу.

Важливою відмінністю цієї функції від більшості інших системних викликів і функцій є те, що у разі невдалого завершення вона повертає не негативне, а позитивне значення, яке визначає код помилки, описаний у файлі <errno.h>. Значення системної змінної errno при цьому не встановлюється. Результатом виконання цієї функції є поява в системі нової нитки виконання, яка виконуватиме функцію, асоційовану з thread'ом, передавши їй специфікований параметр, паралель з вже існуючими нитками виконання процесу.

Створений thread може завершити свою діяльність трьома способами:

· За допомогою виконання функції pthread_exit(). Функція ніколи не повертається в нитку виконання, що викликала її. Об'єкт, на який указує параметр цієї функції, може бути вивчений в іншій нитці виконання, наприклад, в завершився thread, що породила. Цей параметр, отже, повинен указувати на об'єкт, що не є локальним для thread'а, що завершився, наприклад, на статичну змінну;

· За допомогою повернення з функції, асоційованої з ниткою виконання. Об'єкт, на який указує адресу, що повертається функцією, як і у попередньому випадку, може бути вивчений в іншій нитці виконання, наприклад, в завершився thread, що породила, і повинен указувати на об'єкт, що не є локальним для thread'а, що завершився;

· Якщо в процесі виконується повернення з функції main() або де-небудь в процесі (в будь-якій нитці виконання) здійснюється виклик функції exit(), це приводить до завершення всіх thread'ов процесу.



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

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