- •Урок № 61
- •Урок № 62
- •Урок № 72
- •Урок № 73
- •Створення зв'язку з файлом /dev/modem за допомогою команди lisa.
- •Настройка системи Linux для встановлення зв'язку.
- •Як створюється зв'язок з файлом /dev/modem за допомогою команди lisa?
- •Яким чином можна настроїти систему Linux для встановлення зв'язку?
- •Урок № 74
- •Урок № 75
- •Використання програми mail.
- •Урок № 76
- •Використання клієнта kpackage
- •Як використовується клієнт kpackage?
- •Урок № 77
- •Урок № 80
- •Урок № 82
- •Урок № 84
- •Урок № 85
- •Урок № 86
- •Урок № 87
- •Урок № 88
- •Урок № 89
- •Урок № 90
- •Урок № 92
- •Урок № 93
- •Урок № 95
- •Урок № 96
- •Урок № 97
- •Урок № 97
Урок № 88
(згідно навчальної робочої програми)
Тема: «Програмний інтерфейс керування потокам POSIX»
Питання:
Створення потоків POSIX.
Завершення потоків POSIX.
Приєднання потоків POSIX.
Від’єднані потоки. Задания атрибутів потоків POSIX.
Створення потоків POSIX
Щоб додати новий потік у поточний процес, у POSIX використовують функцію pthread_create() із таким синтаксисом:
#include<pthread.h>
intpthread_create(pthread_t *th. pthread_attr_t *attr,
void*(*thread_fun)(void *), void *arg);
Розглянемо параметри цієї функції:
th— покажчик на заздалегідь визначену структуру типу pthread_t, яка далі буде передана в інші функції роботи з потоками; далі називатимемо її дескриптором потоку (threadhandle);
attr— покажчик на структуру з атрибутами потоку;
thread_fun- покажчик на функцію потоку, щомає описуватися як
void *mythread_fun(void *value) {
// виконання коду потоку
}
arg — дані, щопередаються у функцію потоку (туди вони потраплять як параметр value).
Ось приклад створення потоку POSIX:
#include<pthread.h>
// функція потоку
void *thread_fun(void *num) {
printf(“потік номер *d\n“. (int)num):
}
// ...
pthread_tth;
// створюємо другий потік
pthread_create (&th. NULL. thread_fun, (void *)++thread_num):
// тут паралельно виконуються два потоки
Для потоків, створених у такий спосіб, розмір стека задають за замовчуванням. Крім того, після завершення їх обов’язково треба приєднати.
Новий потік починає виконуватися паралельно із потоком, що його створив.
Завершення потоків POSIX
Для завершення потоку достатньо дійти до кінця його функції потоку thread_fun( ) або викликати з неї pthread_exit():
#include<pthread.h>
voidpthread_exit(void *retval);
Параметр retval задає код повернення.
Для коду початкового потоку програми є дві різні ситуації:
Виклик функції pthread_exit() використовують тільки для приєднуваних потоків, оскільки він не звільняє ресурси потоку — за це відповідає той, хто приєднає потік. Насправді, якщо такий потік не буде приєднаний негайно після завершення, його інформація залишиться в системі й може бути зчитана пізніше.
Приєднання потоків POSIX
Для очікування завершення потоків використовують функцію pthread_join()
Вона має такий синтаксис:
int pthread_join(pthread_t th. void **status);
Ця функція блокує потік, де вона була викликана, доти, доки потік, заданий дескриптором th, не завершить своє виконання. Потік, на який очікують, має існувати в тому самому процесі й не бути від’єднаним. Якщо status не є нульовим покажчиком, після виклику він вказуватиме на дані, повернені потоком (аргумент функції pthread_exit( )). Якщо потік уже завершився до моменту виклику функції pthread_join(), його інформація має бути зчитана негайно.
Після приєднання потоку інформацію про нього повністю вилучають із системи, тому коли кілька потоків очікували на той самий потік, його приєднає тільки один із них, для решти буде повернено помилку.
Часто програмісти забувають виконувати операцію приєднання під час завершення приєднуваних потоків. У підсумку ресурси таких потоків не звільняються системою, що призводить до витікання пам’яті.
Від’єднані потоки. Задания атрибутів потоків POSIX
Для того, щоб отримати від’єднаний потік, треба задати відповідні атрибути потоку, виконавши такі дії.
Описати змінну для їхнього зберігання (атрибути потоку відображає структура даних pthread_attr_t):
pthread_attr_tattr;
Ініціалізувати цю змінну так: pthread_attr_init(&attr);
Задати атрибут за допомогою виклику спеціальної функції (різним атрибутам відповідають різні функції).
Для задания атрибута, який визначає, чи буде цей потік від’єднаним чи ні, використовують таку функцію:
pthread_attr_setdetachstate(pthread_attr_t attr. intdetachstate);
Другим параметром може бути одне зі значень:
THRЕAD_CRЕATЕ_JOINABLЕ (приєднуваний потік);
PTHREAD_CREATE_DETACHED (від’єднаний потік).
Контрольні питання:
Як здійснюється створення потоків POSIX?
Як здійснюється завершення потоків POSIX?
Як здійснюється приєднання потоків POSIX?
Як отримують від’єднані потоки?
Як задаються атрибутів потоків POSIX?
Які параметри має функція pthread_create()?
Література: Шеховцов В.А. Операційні системи. – К.: Видавнича група BHV, 2005. – 576 с.: іл., стор. 76-82.
