Книга: Основы программирования в Linux
Одновременное выполнение
Разделы на этой странице:
Одновременное выполнение
В упражнении 12.2 показано, как написать программу, которая проверяет одновременное выполнение двух потоков. (Вы, конечно, применяете однопроцессорную систему, ЦП будет искусно переключаться между потоками, а не одновременно выполнять оба потока, используя отдельные ядра процессора аппаратными средствами.) Поскольку вы не встречались еще с какими-либо функциями синхронизации потоков, это будет очень неэффективная программа, делающая нечто, именуемое опросом (polling) двух потоков. И снова вы воспользуетесь тем, что все, за исключением локальных переменных функции, совместно используется двумя потоками в процессе.
Упражнение 12.2. Одновременное выполнение двух потоков
Программа thread2.c в этом упражнении создается за счет небольших изменений программы thread1.c. Вы добавите дополнительную глобальную переменную для определения выполняющегося потока.
Примечание
Файлы с полными текстами примеров можно загрузить с Web-сайта книги.
int run_now = 1;
Задайте run_now
равной 1, когда выполняется функция main
, и 2, когда выполняется новый поток.
В функцию main
после создания нового потока добавьте следующий код:
int print_count1 = 0;
while (print_count1+ < 20) {
if (run_now == 1) {
printf("1");
run_now = 2;
} else {
sleep(1);
}
}
Если переменная run_now
равна 1, выведите "1" и присвойте переменной значение 2. В противном случае вы на короткое время засыпаете и снова проверяете значение. Вы ждете, пока значение изменится на 1, проверяя время от времени снова. Этот прием называется циклам активного или деятельного ожидания (busy wait), несмотря, на то, что в данном случае программа засыпает на секунду между очередными проверками. Позже в этой главе вы увидите, как сделать это лучше.
В функции thread_function
, где выполняется ваш новый поток, вы делаете примерно то же самое, но с противоположными значениями.
int print_count2 = 0;
while (print_count2++ < 20) {
if (run_now == 2) {
printf("2");
run_now = 1;
} else {
sleep(1);
}
}
Вы удаляете переданные параметр и возвращаемое значение, т.к. они вас больше не интересуют.
Когда вы выполните программу, то увидите следующий вывод. (Вы можете обнаружить, что для формирования вывода, особенно на машине с одноядерным ЦП, программе потребуется несколько секунд.)
$ cc -D_REENTRANT thread2.с -о thread2 -lpthread
$ ./thread2
12121212121212121212
Waiting for thread to finish...
Thread joined
Как это работает
Каждый поток заставляет другой поток выполняться, задавая переменную run_now
и затем ожидая, пока другой поток не изменит значение, чтобы можно было продолжить выполнение. Из программы видно, что выполнение переходит от одного потока к другому автоматическими кроме того, она демонстрирует точку, совместно используемую обоими потоками, — переменную run_now
.
- 2.3.2. Одновременное выполнение задач
- 8.4.5. Выполнение внешних команд
- Выполнение макросов
- Практическая работа 46. Выполнение расчетов с использованием Мастера функций
- 9.4.2. Регистрация времени, потраченного на выполнение задания
- 15.3.2. Установка контрольных точек, пошаговое выполнение и отслеживаемые точки
- 5.4. Управление интерфейсом и выполнение команд
- Выполнение Linuxconf на удаленном компьютере
- Выполнение AMANDA
- Pacкpытиe u выполнение
- Выполнение XSLT-преобразований в Java
- Влияние ошибок на выполнение программ