Каждый разработчик рано или поздно сталкивается с необходимостью создания потока. Ведь нельзя решить практически ни одну сложную задачу выполняя только одну задачу за раз.
В Linux имеется собственная реализация потоков. Для создания потока существует функция pthread_create:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
- pthread_t *thread — указатель на поток
- const pthread_attr_t *attr — атрибуты потока (если NULL — стандартные)
- void *(*start_routine)(void*) — имя функции выполняемой в потоке
- void *arg — параметр передаваемый функции.
Возвращает данная функция 0 если всё успешно и номер ошибки если нет.
После создания потока можно приступать к ожиданию его завершения — pthread_join:
int pthread_join(pthread_t thread, void **value_ptr);
Первый параметр — указатель на поток, второй — практически всегда NULL.
Кроме того поток можно завершить досрочно:
pthread_cancel(thread);
Теперь давайте создадим небольшую программу для наглядности.
Создадим приложение с двумя потоками.
Библиотеки:
#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <pthread.h> #include <iostream> using namespace std;
Определим функцию для потока:
void * thread_func(void *arg){ int i; int loc_id = * (int *) arg; for (i = 0; i < 4; i++) { printf("Поток %i работает\n", loc_id); sleep(1); } }
В функции main зададим основные переменные:
int main(int argc, char * argv[]){ int id1, id2, result; pthread_t thread1, thread2;
Зададим идентификатор потока. Не путайте с системным идентификатором! Это всего лишь переменная для нашей программы!
id1 = 1;
Создадим потока и проверим ошибки:
result = pthread_create(&thread1, NULL, thread_func, &id1); if (result != 0) { perror("Создание первого потока!"); return EXIT_FAILURE; }
Тоже повторим для второго потока:
id2 = 2; result = pthread_create(&thread2, NULL, thread_func, &id2); if (result != 0) { perror("Создание второго потока"); return EXIT_FAILURE; }
Отделим момент для наглядности примера:
sleep(2); cout << "Ждём конца!\n";
Ждём завершения первого и второго потока:
result = pthread_join(thread1, NULL); if (result != 0) { perror("Ждём первый поток"); return EXIT_FAILURE; } result = pthread_join(thread2, NULL); if (result != 0) { perror("Ждём второй поток"); return EXIT_FAILURE; }
Выводим сообщение о конце и выходим из программы:
printf("Done\n"); return EXIT_SUCCESS; }
Вывод программы такой:
Поток 1 работает Поток 2 работает Поток 1 работает Поток 2 работает Ждём конца! Поток 1 работает Поток 2 работает Поток 1 работает Поток 2 работает Done
Обратите ваше внимание на то, что чтобы откомпилировать программу придётся задать флаг -D_REENTERANT и библиотеки:
g++ threads.cpp -D_REENTERANT -I/usr/include/nptl -L/usr/lib/nptl –lpthread -o threads
Хотя я создавал проект в Qt Creator и qmake разобрался сам 😉
Огромное спасибо, все доступно и понятно!)