Мы уже знаем, как программа порождает дочерний процесс. Первоначально он находится в родительской программе, получая копии ее виртуальной памяти, дескрипторов файлов и т.п. Модификация содержимого памяти, закрытие файлов и другие подобные действия в дочернем процессе не влияют на работу родительского процесса и наоборот. С другой стороны, когда программа создает поток, ничего не копируется. Оба потока — старый и новый — имеют доступ к общему виртуальному пространству, общим дескрипторам файлов и другим системным ресурсам. Если, к примеру, один поток меняет значение переменной, это изменение отражается на другом потоке. Точно так же, когда один поток закрывает файл, второй поток теряет возможность работать с этим файлом. В связи с тем что процесс и все его потоки могут выполнять лишь одну программу одновременно, как только одни из потоков вызывает функцию семейства exec()
В Linux реализована библиотека API-функций работы с потоками, соответствующая стандарту POSIX (она называется Pthreads). Все функции и типы данных библиотеки объявлены в файле
-lpthread
в командной строке.4.1. Создание потока
Каждому потоку в процессе назначается собственный идентификатор. При ссылке на идентификаторы потоков в программах, написанных на языке С или C++, нужно использовать тип данных pthread_t
После создания поток начинает выполнять
void*
и возвращают значение аналогичного типа. Этот параметр называется Функция pthread_create()
■ Указатель на переменную типа pthread_t
■ Указатель на объект
NULL
, поток будет создан со стандартными атрибутами. Подробнее данная тема обсуждается в разделе 4.1.5, "Атрибуты потоков".■ Указатель на потоковую функцию. Функция имеет следующий тип:
void* (*)(void*)
■ Значение аргумента потока (тип void*
Функция pthread_create()
Программа, представленная в листинге 4.1, создает поток, который непрерывно записывает символы 'x' в стандартный поток ошибок. После вызова функции pthread_create()
#include
#include
/* Запись символов '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' чередуются самым непредсказуемым образом.