Чтение онлайн

на главную - закладки

Жанры

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

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

void*
и возвращают значение аналогичного типа. Этот параметр называется аргументом потока. Через него программы могут передавать данные потокам. Аналогичным образом через возвращаемое значение программы принимают данные от потоков.

Функция

pthread_create
создает новый поток. Ей передаются следующие параметры.

■ Указатель на переменную типа

pthread_t
, в которой сохраняется идентификатор нового потока.

■ Указатель на объект атрибутов потока. Этот объект определяет взаимодействие потока с остальной частью программы. Если задать его равным

NULL
, поток будет создан со стандартными атрибутами. Подробнее данная тема обсуждается в разделе 4.1.5, "Атрибуты потоков".

■ Указатель на потоковую функцию. Функция имеет следующий тип:

void* (*)(void*)

■ Значение аргумента потока (тип

void*
). Данное значение без каких-либо изменений передается потоковой функции.

Функция

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

Программа, представленная в листинге 4.1, создает поток, который непрерывно записывает символы 'x' в стандартный поток ошибок. После вызова функции

pthread_create
основной поток начинает делать то же самое, но вместо символов 'x' печатаются символы 'o'.

Листинг 4.1. (thread-create.c) Создание потока

#include <pthread.h>

#include <stdio.h>

/* Запись символов 'x' в поток stderr.

Параметр не используется.

Функция никогда не завершается. */

void* print_xs(void* unseed) {

 while (1)

fputc('x', stderr);

 return NULL;

}

/* Основная программа. */

int main {

 pthread_t thread_id;

 /* Создание потока. Новый поток выполняет

функцию print_xs. */

 pthread_create(&thread_id, NULL, &print_xs, NULL);

 /*
Непрерывная запись символов 'o' в поток stderr. */

 while (1)

fputc('o', stderr);

 return 0;

}

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

% cc -o thread-create thread-create.c -lpthread

Запустите программу, и вы увидите, что символы 'x' и 'o' чередуются самым непредсказуемым образом.

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

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

4.1.1. Передача данных потоку

Потоковый аргумент — это удобное средство передачи данных потокам. Но поскольку его тип

void*
, данные содержатся не в самом аргументе. Он лишь должен указывать на какую-то структуру или массив. Лучше всего создать для каждой потоковой функции собственную структуру, в которой определялись бы "параметры", ожидаемые потоковой функцией.

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

Программа, приведенная в листинге 4.2, напоминает предыдущий пример. На этот раз создаются два потока: один отображает символы 'x', а другой — символы 'o'. Чтобы вывод на экран не длился бесконечно, потокам передается дополнительный аргумент, определяющий, сколько раз следует отобразить символ. Одна и та же функция

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

Листинг 4.2. (thread-create2.c) Создание двух потоков

#include <pthread.h>

#include <stdio.h>

/* Параметры для функции char_print. */

struct char_print_parms {

 /* Отображаемый символ. */

 char character;

 /* Сколько раз его нужно отобразить. */

 int count;

};

/* Запись указанного числа символов в поток stderr. Аргумент

Поделиться:
Популярные книги

Письма

Пелусиот Исидор
Религия и эзотерика:
религия
5.00
рейтинг книги
Письма

Неучтенный элемент. Том 12

NikL
12. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 12

Царь Живых

Точинов Виктор Павлович
Фантастика:
ужасы и мистика
6.25
рейтинг книги
Царь Живых

Старый тракт (сборник)

Марков Георгий Мокеевич
Сибириада
Проза:
современная проза
7.12
рейтинг книги
Старый тракт (сборник)

Моцарт и его время

Луцкер Павел
Документальная литература:
биографии и мемуары
научпоп
5.00
рейтинг книги
Моцарт и его время

Третий. Том 2

INDIGO
2. Отпуск
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий. Том 2

Дитя прибоя

Трофимов Ерофей
Дитя прибоя
Фантастика:
боевая фантастика
попаданцы
фэнтези
5.25
рейтинг книги
Дитя прибоя

Газлайтер. Том 10

Володин Григорий Григорьевич
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

Йога т4

Васиштха
5.00
рейтинг книги
Йога т4

Кодекс Охотника. Книга XII

Винокуров Юрий
12. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XII

Хвак

О'Санчес
5.00
рейтинг книги
Хвак

Вся правда о раковых заболеваниях. Новый подход к лечению и профилактике онкологии

Куомо Маргарет
Справочная литература:
прочая справочная литература
5.00
рейтинг книги
Вся правда о раковых заболеваниях. Новый подход к лечению и профилактике онкологии

Начальник милиции. Книга 3

Дамиров Рафаэль
3. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 3

Верховный суд СССР

Коллектив авторов
Научно-образовательная:
история
юриспруденция
5.00
рейтинг книги
Верховный суд СССР