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

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

Жанры

Основы программирования в Linux
Шрифт:

Thread is still running (2)...

Canceling thread...

Waiting for thread to finish...

$

Как это работает

После того как новый поток был создан обычным способом, основной поток засыпает (чтобы дать новому потоку время для запуска) и затем отправляет запрос на отмену потока.

sleep(3);

printf("Cancelling thread...\n");

res = pthread_cancel(a_thread);

if (res != 0) {

 perror("Thread cancelation failed");

 exit(EXIT_FAILURE);

}

В

созданном потоке вы сначала задаете состояние отмены, чтобы разрешить отмену потока:

res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

if (res != 0) {

 perror("Thread pthread_setcancelstate failed");

 exit(EXIT_FAILURE);

}

Далее вы задаете тип отмены

PTHREAD_CANCEL_DEFERRED
:

res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

if (res != 0) {

 perror("Thread pthread_setcanceltype failed");

 exit(EXIT_FAILURE);

}

И в конце поток ждет отмену:

for (i = 0; i < 10; i++) {

 printf("Thread is still running (%d)...\n", i);

 sleep(1);

}

Потоки в изобилии

До настоящего момента у нас всегда был обычный поток исполнения программы, создающий еще только один поток. Тем не менее мы не хотим, чтобы вы думали, что можно создать только один дополнительный поток (упражнение 12.8).

Упражнение 12.8. Много потоков

В заключительном примере этой главы thread8.c мы покажем, как создать несколько потоков в одной и той же программе и затем собрать их снова в последовательности, отличающейся от порядка их создания.

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <pthread.h>

#define NUM_THREADS 6

void *thread_function(void *arg);

int main {

 int res;

 pthread_t a_thread[NUM_THREADS];

 void *thread_result;

 int lots_of_threads;

 for (lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads++) {

res = pthread_create(&(a_thread[lots_of_threads]), NULL, thread_function, (void*)&lots_of_threads);

if (res != 0) {

perror("Thread creation failed");

exit(EXIT_FAILURE);

}

sleep(1);

 }

 printf("Waiting for threads' to finish...\n");

 for(lots of_threads = NUM_THREADS - 1; lots_of_threads >= 0; lots_of_threads--) {

res = pthread_join(a_thread[lots_of_threads], &thread_result);

if (res == 0) {

printf("Picked up a thread\n");

} else {

perror("pthread_join failed");

}

 }

 printf("All done\n");

 exit(EXIT_SUCCESS);

}

void *thread_function(void *arg) {

 int my_number = *(int*)arg;

 int rand_num;

 printf("thread_function is running. Argument was %d\n", my_number);

 rand_num = 1 + (int)(9.0*rand / (RAND_MAX+1.0));

 sleep(rand_num);

 printf("Bye from %d\n", my_number);

 pthread_exit(NULL);

}

Выполнив

эту программу, вы получите следующий вывод:

$ ./thread8

thread_function is running. Argument was 0

thread_function is running. Argument was 1

thread_function is running. Argument was 2

thread_function is running. Argument was 3

thread_function is running. Argument was 4

Bye from 1

thread_function is running. Argument was 5

Waiting for threads to finish...

Bye from 5

Picked up a thread

Bye from 0

Bye from 2

Bye from 3

Bye from 4

Picked up a thread

Picked up a thread

Picked up a thread

Picked up a thread

Picked up a thread

All done

Как видите, вы создали много потоков и разрешили им завершаться в произвольной последовательности. В этой программе есть маленькая ошибка, которая проявит себя, если вы удалите вызов sleep из цикла, запускающего потоки. Мы включили ее, чтобы показать, как вы должны быть внимательны при написании программ, применяющих потоки. Вы нашли ее? В следующем разд. "Как это работает" будет дано объяснение.

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

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Мы друг друга не выбирали

Кистяева Марина
1. Мы выбираем...
Любовные романы:
остросюжетные любовные романы
прочие любовные романы
современные любовные романы
5.00
рейтинг книги
Мы друг друга не выбирали

Гримуар темного лорда IV

Грехов Тимофей
4. Гримуар темного лорда
Фантастика:
фэнтези
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Гримуар темного лорда IV

Старый, но крепкий

Крынов Макс
1. Культивация без насилия
Фантастика:
рпг
уся
попаданцы
5.00
рейтинг книги
Старый, но крепкий

Дважды одаренный

Тарс Элиан
1. Дважды одаренный
Фантастика:
альтернативная история
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Дважды одаренный

Александр Агренев. Трилогия

Кулаков Алексей Иванович
Александр Агренев
Фантастика:
альтернативная история
9.17
рейтинг книги
Александр Агренев. Трилогия

#Бояръ-Аниме. Газлайтер. Том 24

Володин Григорий Григорьевич
24. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 24

Как я строил магическую империю 6

Зубов Константин
6. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 6

Поводырь

Щепетнов Евгений Владимирович
3. Ботаник
Фантастика:
фэнтези
6.17
рейтинг книги
Поводырь

Кадет Морозов

Шелег Дмитрий Витальевич
4. Живой лёд
Фантастика:
боевая фантастика
5.72
рейтинг книги
Кадет Морозов

Тринадцатый V

NikL
5. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый V

Я еще барон. Книга III

Дрейк Сириус
3. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще барон. Книга III

Хозяин Стужи 4

Петров Максим Николаевич
4. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Хозяин Стужи 4

Дважды одаренный. Том II

Тарс Элиан
2. Дважды одаренный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Дважды одаренный. Том II