Многопоточное программирование c linux

Русские Блоги

[Linux] Многопоточное программирование (программирование языка C)

Во-первых, основная концепция нити
По сравнению с процессом MultiPhreading является очень «экономной» многозадачкой. В операционной системе Linux начнется новый процесс
Он назначает независимое адресное пространство для создания многочисленных листов данных для поддержания его сегмента кода, сегмента стека и сегмент данных, который является «дорогой» многозадачкой
Рабочий режим; и запустить несколько потоков в процессе, используйте одно и то же адресное пространство между собой, поделитесь большинством данных, начать
Пространство, потраченное на нить, намного меньше пространства, потраченного на начало процесса, и время, необходимое для переключения друг друга, намного меньше, чем коммутация процесса.
Требуется время.
В качестве автономного объекта он предоставляет потоки для запуска ресурсов и представляют собой статические среды. Нить является основной единицей планирования процессора. если
Сказать, что концепция процесса хорошо описана с автономным поведением операционной системы, концепция потоков хорошо описана при параллельном поведении обработки многоструктурной системы. Быть
Многопоточный режим работы обеспечивает удобный механизм связи между потоками. Так что линия обмена пространствами данных между потоками под тем же процессом
Данные Чэна могут быть использованы непосредственно к другим потокам, что не только быстро и удобно.
Многопоточная программа имеет следующие преимущества: Улучшите реакцию приложений, чтобы система ЦП более эффективной и улучшает структуру программы.

Во-вторых, реализация потока
Метугольник в рамках системы Linux следует за интерфейсом потока POTIX, называемый pthread. Напишите многотехнологичные программы под Linux, вам нужно использовать файлы заголовка
Pthread.h, вам нужно использовать файл библиотеки libpthread.a при подключении. (Так что вам нужно добавить параметры: -lptread)

Читайте также:  Особенности изучения языков программирования

(1) Создание потока: то есть для определения точки записи, чтобы вызвать функцию потока, обычно используемая функция — pthread_create.

 int pthread(pthread_t * thread, pthread_attr_t * attr, void * ( * start_routine) (void *), void arg)); Pthread: идентификатор нитки Attr: недвижимость нить Start_routine: начальный адрес функции запуска потоков (имя функции потока) ARG: параметры функции (параметры, необходимые для функции потока) Возвращаемая стоимость: создать успех - return 0, если не 0, поток создания не удался (eaegain, einval)

(2) поток зависает
Множество потоков в процессе являются общие данные, поэтому они обычно выходят на ресурсы, занимаемые потоками, не будут следовать по потоку.
Прекращение потока выпущено. Так же, как ждать () в процессе, используйте функцию Pthread_join () между нитью, чтобы повесить текущий поток, подождите
Конец нити. Pthread_join () — это функция блокировки потоков, которая вызывает свою функцию, всегда будет дождаться до конца потока ожидания.
Следует отметить, что нить не может быть ждать несколькими потоками, в противном случае первая нить, которая принимает сигнал, успешно возвращается, остальные будут
Возвращает код ошибки.

 int pthread_join(pthread_t th, void ** thread_return); TH: ждущий идентификатор темы Thread_return: пользовательские указатели, используемые для хранения возвратных значений потока ожидания

(3) конец потока: 1. Соответствующая функция потока работает; 2. Вызовите функцию Pthread_exit ()

 void pthread_exit(void * retval) RetVal: код возврата функции, то есть Thread_return
Пустотная резьба (пустота) <> // Функция запуска потоков pthread_t id; pthread(&id,NULL,(void *)thread,NULL); // Создать нить, первый NULL - генерировать нить атрибута по умолчанию, второй нулевой - функция запуска потоков не требует параметров Pthread_join (ID, NULL); // посуде

В-третьих, модифицировать свойства потока
Значения атрибутов потоков не могут быть настроены напрямую, вам необходимо вызвать связанные функции для работы, функция инициализации — Pthread_attr_init, это письмо
Номер должен быть вызван перед функцией Pthread_Create. Объекты атрибутов включают ли связывание, следует ли отделять, складывать адреса, размеры стека и приоритет.
Атрибут по умолчанию не связан, не разделенный, штат 1 МБ по умолчанию и приоритет с тем же уровнем, что и родительский процесс. Для большинства программ используйте по умолчанию
Признание достаточно.

Читайте также:  Android программирование какие языки используются

1, связывание
Об привязке включает в себя еще одну концепцию: легкий процесс LWP (легкий процесс). Это можно понять как поток ядра, система резьба
Распределение ресурсов и контроль потока достигается за счет легких процессов. По умолчанию, сколько световых процессов контролируется системой, прогрессируют свет
Какие потоки контролируются, это состояние называется несвязанным. Привязка того, что нить фиксируется для «связана» на легкой ните. Привязка нити
Имея высокую скорость реакции (планирование нарезки времени процессора — это легкий процесс).
Установив приоритет и уровень планирования процесса привязки, связанный нить может соответствовать требованиям, таким как реакции в реальном времени.

Создать нить привязки: (pthread_attr_setscope)

 pthread_attr_t attr; pthread_t tid; Pthread_attr_init (& attr); // инициализация значение установлено значение по умолчанию Pthread_attr_setscope (& attr, pthread_scope_system); // Настройка состояния связывания pthread_create(&id, &attr, (void *) my_function, NULL); Attr: Указатель на структуру свойств Тип связывания: pthread_scope_system (bind), pthread_scope_process (несвязанный)

2, разделение
Состояние разделения нити определяет нить для прекращения самого.
Не разделенные: исходная нить ждет, чтобы быть созданным концом, и только функция Pthread_join () возвращается к ресурсу.
Отдельно: не допускается другими процессами и немедленно отпустите ресурсы сразу после запуска.

Функция состояния разделения потоков:

 pthread_attr_setdetachstate(pthread_attr_t * attr, int detachstate) Отсоединить: pthread_create_detached, pthread_create_joinable (не разделенная нить)

Если нить установлена ​​на резьбу разделения, эта нить работает очень быстро, вполне вероятно, будет в функции Pthread_Create
Прекращение перед возвратом так, чтобы нить Pthread_Create может получить неправильный номер потока. Чтобы избежать этого,
Обычно называют функцию Pthread_cond_timewait в созданном потоке, пусть эта нить ждать.

3, приоритет
Приоритет хранится в структуре SCEN_PARAM, с функциями pthread_attr_getschedparam и pthread_attr_setschedparam
Магазин. Как правило, приоритет сначала, а затем приоритет изменен, а затем сохраняется назад.

Pthread_attr_t attr; // атрибут Pthread_t TID; // Идентификатор потока SCEN_PARAM PARAM; // Приоритет Int newPrio = 20; // новый приоритет pthread_attr_init(&attr); Pthread_attr_getschedParam (& attr, & param); / Удалить приоритет Param.sched_priority = newPrio; // изменять приоритет Pthread_attr_setschedParam (& attr, & param); // приоритет назад pthread_create(&tid, &attr, (void *)myfunction, NULL);

Четвертый, многопоточный контроль доступа
Из-за ресурсов и адресного пространства многопоточного процесса обмена, единственный способ доступа к этим ресурсам необходимо рассмотреть.
Одна проблема секса.
Существует четкий недостаток: есть только два состояния (блокировка и неблокировка), а условные переменные разрешено блокировать и ждать еще одну строку.
Способ переходных сигналов компенсирует недостаточную Mutex, он часто использует Mutex.

1, Функция pthread_cond_init () — используется для инициализации переменной условия
int pthread_cond_init(pthread_cond_t * cond, __const pthread_condattr_t * cond_attr)

Cond: указывая указатель на структуру pthread_cond_t
Cond_attr: атрибут структура условных переменных (по умолчанию — pthread_process_private)

Переменная состояния инициализации может быть перевоплощена или выпущена только тогда, когда она не используется.
Отпустите функцию переменной условия: pthread_cond_destroy (pthread_cond_t cond)

2, Pthread_cond_wait () Функция — вызвать блокировку потоков на условной переменной
extern int pthread_cond_wait(pthread_cond_t * __restrict__cond,
pthread_mutex_t * __restrict__mutex)

Нить не нарушает точки блокировки к Mutex, а переменная условия COND заблокирована.

3, Pthread_cond_timedwait () Функция — другая функция для блокировки потока
extern int pthread_cond_timedwait __P((pthread_cond_t * __restrict__cond,
pthread_mutex_t * __restrict__mutex, __const struct timespec * __abstime))

Это более часовой параметра, чем функция Thream_cond_wait (), а после времени возникновения, даже если переменная условия не удовлетворена,
Блокировка также выпускается.

4. Функция pthread_cond_signal () — нить, используемая для отпуска, блокируется на переменной условии COND.
extern int pthread_cond_signal(pthread_cond_t * __cond)

Следует отметить, что эта функция должна быть защищена блокировкой Mutex переменной условия, в противном случае условие удовлетворяет сигналу и может находиться в условиях испытаний и
Функция Pthread_Cond_Wait () отправляется между функцией, тем самым вызывая неограниченное ожидание.

5, другие общие функции потока
Получите родительский идентификатор процесса:
pthread pthread_self(void)
Тест, если две строки одинаковы:
int pthread_equal(pthread_t __thread, pthread_t __thread2)
Взаимная инициализация исключения:
int pthread_mutex_init(pthread_mutex_t * , __const pthread_mutexattr_t * )
Уничтожить взаимное исключение:
int pthread_mutex_destroy(pthread_mutex_t *__mutex)
Попробуйте еще раз получить замок (не блокировка) на Mutex (не блокировка)
int pthread_mutex_trylock(pthread_mutex_t *__mutex)
Блокировка взаимного исключения (блокировка)
int pthread_mutex_lock(pthread_mutex_t *__mutex)
Разблокировать взаимное исключение
int pthead_mutex_unlock(pthread_mutex_t *__mutex)
Условие переменная инициализация
int pthread_cond_init(pthread_cond_t *__restrict__cond,
__const pthread_condattr_t *__restrict__cond_attr)
Уничтожьте переменную кондиционера COND
int pthread_cond_destroy(pthread_cond_t *__cond)
Проснимите переменную
int pthread_cond_signal(pthread_cond_t *__cond)
Переменная состояния ожидания
int pthread_cond_wait(pthread_cond_t *__restrict__cond,
pthread_mutex_t * __restrict__mutex)
До указанного времени достигает переменных состояния ожидания переднего
int pthread_cond_timewait(pthread_cond_t *__restrict__cond,
phread_mutex_t *__restrict__mutex, __const struct timespec *__restrict __abstime)

Источник

Программирование C в Linux — потоки pthreads

multithread_lol

Многопоточность в программировании является важным механизмом в наше время. Поэтому я решил посвятить несколько статей этой теме.

В семействах ОС Windows — каждая программа запускает один процесс выполнения, в котором находится как минимум один поток (нить). В процессе может находиться множество потоков, между которыми делится процессорное время. Один процесс не может напрямую обратиться к памяти другого процесса, а потоки же разделяют одно адресное пространство одного процесса. То есть в Windows — процесс это совокупность потоков.

В Linux же немного по-другому. Сущность процесса такая же, как и в Windows — это исполняемая программа со своими данными. Но вот поток в Linux является отдельным процессом (можно встретить название как «легковесный процесс», LWP). Различие такое же — процесс отдельная программа со своей памятью, не может напрямую обратиться к памяти другого процесса, а вот поток, хоть и отдельный процесс, имеет доступ к памяти процесса-родителя [2]. LWP процессы создаются с помощью системного вызова clone() с указанием определенных флагов.

Но также имеется такая вещь, которая называется «POSIX Threads» — библиотечка стандарта POSIX, которая организует потоки (они же нити) внутри процесса. Т.е тут уже распараллеливание происходит в рамках одного процесса.

И тут встает вопрос различия терминов «поток», «процесс», «нить» и т.д. Проблема в том, что в англоязычной литературе данные термины определяются однозначно, у нас же с нашим великим и могучим имеются противоречия, что может привести к дикому диссонансу.

Но это все в общих чертах, для более точной информации следует обратиться к соответствующей литературе, либо к официальной документации, можно почитать man’ы. В конце статьи я приведу несколько полезных ссылок на ресурсы, где более подробно расписано как все работает, а пока займемся практикой.

Я рассмотрю два варианта «распараллеливания» программы — создания потока/нити с помощью функций из pthread.h (POSIX Threads), либо создание отдельного процесса с помощью функции fork().

Сегодня рассмотрим потоки из библиотеки pthread.

Шаблон кода для работы с потоками выглядит следующим образом:

Источник

Оцените статью