» » » » Основы программирования в Linux - Мэтью Нейл

Основы программирования в Linux - Мэтью Нейл

На нашем литературном портале можно бесплатно читать книгу Основы программирования в Linux - Мэтью Нейл, Мэтью Нейл . Жанр: Интернет. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале litmir.org.
Основы программирования в Linux - Мэтью Нейл
Название: Основы программирования в Linux
Дата добавления: 17 сентябрь 2020
Количество просмотров: 378
Читать онлайн

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту readbookfedya@gmail.com для удаления материала

Основы программирования в Linux читать книгу онлайн

Основы программирования в Linux - читать бесплатно онлайн , автор Мэтью Нейл
В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стан­дартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым. Для начинающих Linux-программистов
Перейти на страницу:

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 из цикла, запускающего потоки. Мы включили ее, чтобы показать, как вы должны быть внимательны при написании программ, применяющих потоки. Вы нашли ее? В следующем разд. "Как это работает" будет дано объяснение.

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

На сей раз вы создаете массив идентификаторов потоков:

pthread_t a_thread[NUM_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);

}

Затем потоки сами по себе ждут в течение случайного промежутка времени, прежде чем начать выполнение:

void *thread_function(void *arg) {

 int my_number = *(int *)arg;

 int rand_num;

 printf("thread_function is running. Argument was %dn", my_number);

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

 sleep(randnum);

 printf("Bye from %dn", my_number);

 pthread_exit(NULL);

}

В это время в основном (исходном) потоке вы ждете, чтобы собрать потоки, но не в том порядке, в каком вы их создали:

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 threadn");

 } else {

  perror("pthread_join failed");

 }

}

Если вы попробуете выполнить программу без вызова

sleep
, то увидите странный эффект: некоторые потоки запускаются с одним и тем же номером, например, вы можете получить вывод, похожий на следующий:

thread_function is running. Argument was 0

thread_function is running. Argument was 2

thread_function is running. Argument was 2

thread_function is running. Argument was 4

thread_function is running. Argument was 4

thread_function is running. Argument was 5

Waiting for threads to finish...

Bye from 5

Picked up a thread

Bye from 2

Bye from 0

Bye from 2

Bye from 4

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

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

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);

Если поток

main
выполняется достаточно быстро, он может искажать аргумент (
lots_of_threads
) для некоторых потоков. Поведение, подобное этому, наблюдается, когда недостаточно внимания уделяется совместно используемым переменным и множественным путям исполнения (multiple execution paths). Мы предупреждали вас о том, что программирование потоков требует повышенного внимания при разработке! Для исправления ошибки вам следует передавать непосредственно значение следующим образом:

res = pthread_create(&(a_thread[lots_of_threads]), NULL,

 thread_function, (void *)lots_of_threads);

и конечно изменить

thread_function
:

void *thread_function(void *arg) {

 int my_number = (int)arg;

Все исправления, выделенные цветом, показаны в программе thread8a.c.

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>

Перейти на страницу:
Комментариев (0)