13 февр. 2011 г.

Пример многопоточности в C/C++ используя библиотеку pthread

Пример многопоточности в C/C++ используя библиотеку pthread

Статья является моим условным переводом с английского статьи:
http://programming-in-linux.blogspot.com/2008/03/multithreading-example-in-cc-using.html

Следующий листинг — простой пример демонстрирующий как вы можете создавать потоки использую POSIX pthread библиотеку.

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

Так же пример демонстрирует как вы можете передавать данные из родителя в дочерний поток. Это выполняется используя структуру заполненную заранее нужными данными. Эта структура передается с помощью основного 'void *' указателя на функцию pthread_create.



Структура задана с некоторым произвольным количеством инструкций дочернего процесса для засыпания при этом числе. Это делается для демонстрационных целей и следовательно приводит к выполнению вывода программы различными при каждом запуске.

Для того чтобы откомпилировать этот листинг вам нужно использовать gcc или g++ и так же линковать с pthread библиотекой иначе получите ошибку "undefined reference" на этапе линковки.
Таким образом вы можете откомпилировать следующим образом:
g++ -o thread_example.out thread_example.cc -lpthread

Имейте в виду что по некоторым обычаям linux и unix вам не нужно использовать -lpthread но нужно использовать -pthread (без 'l'):
g++ -o thread_example.out thread_example.cc -pthread

Следующий листинг — пример многопоточности:
Наслаждайтесь!
#include
#include
#include
#include
#include
#include
typedef struct my_struct {
int data;
int random_number;
}my_struct_t;
/*===========================================================================*/
void * thread(void * str) {
/*===========================================================================*/
my_struct_t *local_str = (my_struct_t *)str;
int i;
for (i=0;i<5;i++) { sleep(local_str->random_number);
printf("Hello! I am thread %d, i was sleeping for %d seconds\n",
local_str->data,
local_str->random_number);
}
}
/*===========================================================================*/
int main(int argc, char **argv){
/*===========================================================================*/
sigset_t oSignalSet;
sigemptyset(&oSignalSet);
sigaddset(&oSignalSet, SIGINT);
sigaddset(&oSignalSet, SIGABRT);
sigaddset(&oSignalSet, SIGQUIT);
pthread_sigmask(SIG_BLOCK, &oSignalSet, NULL);
pthread_t iThreadId;
//
// Обьявляем переменную для хранения секунд
//
time_t seconds;
//
// Get value from system clock and
// place in seconds variable.
//
time(&seconds);
//
// Convert seconds to a unsigned
// integer.
//
srand((unsigned int) seconds);
my_struct_t st1;
my_struct_t st2;
my_struct_t st3;
st1.data = 1;
st2.data = 2;
st3.data = 3;
st1.random_number = rand()%10;
st2.random_number = rand()%10;
st3.random_number = rand()%10;
printf("Parent: Creating and calling threads...\n");
int iReturnValue1 = pthread_create(&iThreadId, NULL, &thread, (void *)&st1);
int iReturnValue2 = pthread_create(&iThreadId, NULL, &thread, (void *)&st2);
int iReturnValue3 = pthread_create(&iThreadId, NULL, &thread, (void *)&st3);
if (iReturnValue1 < 0 || iReturnValue2 < 0 || iReturnValue2 < 0) {
printf("error creating thread '%s'.\n", strerror(errno));
}
int iSignalNumber;
sigwait(&oSignalSet, &iSignalNumber);
printf("exit after receiving signal #%d.\n", iSignalNumber);
exit(0);
}

Комментариев нет:

Отправить комментарий