Основы программирования в Linux
Основы программирования в Linux читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
printf("Waiting for thread to finish...n");
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror("Thread join-failed");
exit(EXIT_FAILURE);
}
printf("Thread-joined, it returned %sn", (char *)thread_result);
printf("Message is now %sn", message);
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg) {
printf("thread_function is running. Argument was %sn", (char *)arg);
sleep(3);
strcpy(message, "Bye!");
pthread_exit("Thank you for the CPU time");
}
Итак:
1. Перед компиляцией программы вы должны убедиться в том, что определен макрос
_REENTRANT
_POSIX_C_SOURCE
2. Далее вы должны убедиться в том, что программа скомпонована с подходящей библиотекой потоков. В случае маловероятной ситуации применения старой версии дистрибутива Linux, в которой NPTL не является библиотекой потоков по умолчанию, возможно, у вас возникнет желание обновить ее, хотя большая часть программного кода, приведенного в этой главе, совместима со старой реализацией потоков в Linux. Легкий способ проверить — заглянуть в файл /usr/include/pthread.h. Если в этом файле приведен в качестве даты авторского права (copyright date) 2003 г. или более поздний, почти наверняка у вас реализация NPTL. Если указана более ранняя дата, может быть, самое время получить современную версию дистрибутива Linux.
3. Определив и установив нужные файлы, вы можете откомпилировать и скомпоновать вашу программу следующим образом:
$ <b>cc -D_REENTRANT -I/usr/include/nptl threadl.с -о thread1 -L/usr/lib/nptl -lpthread</b>
Если в вашей системе по умолчанию установлена NPTL (что очень вероятно), почти наверняка вам не нужны опции
-I
-L
$ <b>cc -D_REENTRANT thread1.с -о thread1 -lpthread</b>
В данной главе мы будем применять этот более простой вариант строки компиляции.
4. Когда вы выполните эту программу, то увидите следующие строки:
$ <b>./thread1</b>
Waiting for thread to finish...
thread_function is running. Argument was Hello World
Thread joined, it returned Thank you for the CPU time
Message is now Bye!
Стоит потратить немного времени на анализ данной программы, поскольку мы будем использовать ее как основу в большинстве примеров этой главы.
Как это работает
Вы объявляете прототип функции, которую вызовет поток, когда вы его создадите:
void *thread_function(void *arg);
Как требует функция
pthread_create
void
void
thread_function
В функции
main
pthread_create
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, (void *)message);
Вы передаете адрес объекта типа
pthread_t
NULL
Если вызов завершился нормально, теперь выполняются два потока. Исходный поток (
main
pthread_create
thread_function
Исходный поток проверяет, запустился ли новый поток, и затем вызывает функцию
pthread_join
res = pthread_join(a_thread, &thread_result);
Здесь вы передаете идентификатор потока, который ждете, чтобы присоединить, и указатель на результат. Эта функция, прежде чем вернуть управление, будет ждать, пока другой поток не завершится. Затем она выводит возвращаемое из потока значение и содержимое переменной и завершается.
Новый поток начинает выполнение, запуская функцию
thread_function
main
message
fork
pthread_create
message
Одновременное выполнение
В упражнении 12.2 показано, как написать программу, которая проверяет одновременное выполнение двух потоков. (Вы, конечно, применяете однопроцессорную систему, ЦП будет искусно переключаться между потоками, а не одновременно выполнять оба потока, используя отдельные ядра процессора аппаратными средствами.) Поскольку вы не встречались еще с какими-либо функциями синхронизации потоков, это будет очень неэффективная программа, делающая нечто, именуемое опросом (polling) двух потоков. И снова вы воспользуетесь тем, что все, за исключением локальных переменных функции, совместно используется двумя потоками в процессе.
Программа thread2.c в этом упражнении создается за счет небольших изменений программы thread1.c. Вы добавите дополнительную глобальную переменную для определения выполняющегося потока.
Файлы с полными текстами примеров можно загрузить с Web-сайта книги.
int run_now = 1;