Categories: C/C++

pthreads/

Необходимость написания многопоточных приложений возникает весьма и весьма часто. В мире C/C++ эту задачу можно решать по-разному. Так в стандарте C++11 и старше есть std::thread и другие примитивы. Также поддержка трэдов есть в стандарте C11 (threads.h). Однако если эти стандарты вам по каким-то причинам не доступны, или ваше приложение не планируется в обозримом будущем портировать под Windows, можно воспользоваться старой-доброй библиотекой pthreads.

Если для сборки проекта вы используете CMake , pthreads подключается проще простого:

find_library ( PTHREAD_LIBRARY pthread )
# …
target_link_libraries ( main ${PTHREAD_LIBRARY} )

Новый трэд создается как-то так:

#include <pthread.h>

static void * _workerThreadProc ( void * rawArg ) {
/* … достаем аргументы по указателю rawArg … */

/* No other thread is going to join() this one */
pthread_detach ( pthread_self ( ) ) ;

/* … тут всякая полезная нагрузка … */

pthread_exit ( nullptr ) ;
}

// …

pthread_t thr ;
if ( pthread_create ( & thr, nullptr, _workerThreadProc, ( void * ) arg ) ! = 0 )
throw std :: runtime_error ( «pthread_create() failed» ) ;

Если планируется дожидаться завершения трэда, нужно закомментировать строчку про pthread_detach и использовать pthread_join. Подробности вы найдете в соответствующих man-страницах.

Отдельная тема — это взаимодействие трэдов с сигналами. Например, при написании сетевых приложений, часто требуется блокировать SIGPIPE . Делается это следующим образом:

void _ignoreSigpipe ( ) {
sigset_t msk ;
sigemptyset ( & msk ) ;
sigaddset ( & msk, SIGPIPE ) ;
if ( pthread_sigmask ( SIG_BLOCK, & msk, nullptr ) ! = 0 )
throw std :: runtime_error ( «pthread_sigmask() failed» ) ;
}

Трэды сами по себе не очень полезны, если нет каких-то примитивов синхронизации. Самый простой примитив, предлагаемый pthreads — это мьютекс:

pthread_mutex_t my_lock ;

// …

pthread_mutex_lock ( & my_lock ) ;
// do something
pthread_mutex_unlock ( & my_lock ) ;

Также есть чуть более интересный примитив — rwlock:

pthread_rwlock_t my_rwlock ;

// инициализация
if ( pthread_rwlock_init ( & my_rwlock, NULL ) ! = 0 )
throw std :: runtime_error ( «pthread_rwlock_init() failed» ) ;

// лок на чтение
pthread_rwlock_rdlock ( & my_rwlock ) ;

// лок на запись
pthread_rwlock_wrlock ( & my_rwlock ) ;

// анлок
pthread_rwlock_unlock ( & my_rwlock )

// деинициализация
pthread_rwlock_destroy ( & my_rwlock ) ;

Атомарных переменных, насколько мне известно, pthread не предлагает. Однако при сильной необходимости ничто не мешает использовать атомарные переменные из C++11.

В общем-то, описанного выше в 90% случаев будет вполне достаточно для написания многопоточных приложений при помощи pthreads. Более полный пример можно найти в этом репозитории на GitHub . Во всяком случае, до коммита a46c9835 pthreads там еще использовались. В будущем ситуация может и поменяться.

А как вы пишите многопоточные приложения на C/C++?

Дополнение: Также вас могут заинтересовать посты Написание многопоточных приложений на C++11 и старше и Пример простейшей многопоточной программы на WinAPI .

admin

Share
Published by
admin
Tags: C/C++

Recent Posts

Что такое Zulip

Zulip — программное обеспечение для реализации корпоративного чата. Разработан в 2012 году, в 2014 был…

4 месяца ago

Что такое Zookeeper

Zookeeper — cервис-координатор, который позволяет обеспечить контроль синхронизации данных. Разработан на Java компанией Apache Software…

4 месяца ago

Что такое Zimbra

Zimbra — программное обеспечение для реализации почтового сервиса или, если сказать точнее, автоматизации совместной деятельности…

4 месяца ago

Что такое Zabbix

Zabbix — бесплатная система мониторинга. Позволяет отслеживать состояние сетевых узлов, компьютеров и серверов. Возможности: Поддержка…

4 месяца ago

Что такое YouTube

YouTube — компания-владелец одноименного портала для просмотра и хранения видео. Чтобы пользоваться данным порталом достаточно…

4 месяца ago

Что такое yota

Yota — провайдер, предоставляющий доступ к сети Интернет по беспроводной связи. Впервые, сервис начал работать…

4 месяца ago