Другое

Что такое многопоточность в языке С: методы синхронизации

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

Многозадачность свойственна устройствам, средам выполнения и операционным системам и несет в себе возможность параллельно и одновременно обрабатывать несколько поставленных задач. Задачи не связаны между собой и могут обрабатываться отдельно друг от друга.

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

Поток является отдельной ветвью кода одной программы, которая может выполняться параллельно с другими ветвями кода этой же программы.

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

Многопоточность в С

Раньше многопоточность в С реализовывалась с применением дополнительных кроссплатформенных библиотек, например:

  • OpenMP;

  • OpenTheads;

  • POCO Thead;

  • Zthread;

  • Pthreads-w32;

  • и др.

В «свежих» языках Си многопоточность реализовывается при помощи класса «std::thread», где «std::thread» является классом каждого отдельного потока. Теперь новый поток запускается довольно просто: необходимо создавать новый объект потока и передавать исполняемый код для вызова в конструктор объекта. При создании нового объекта будет запускаться новый поток.

Многопоточность в Си: класс «std::thread»

Чтобы использовать многопоточность в С, необходимо выполнить ряд действий:

  1. Обязательно записать заголовочный файл «#include <thread>».

  2. Каждый отдельный поток обозначать классом «std::thread t(callable_object, arg1, arg2 ..)». 

Как выглядит запуск потока в С на примере:

#include <iostream>

#include <thread>

#include <string>

void say_hello(const std::string& name) {

std::cout << "Привет! " << name << std::endl;

}

int main(int argc, char * argv[]) {

std::thread th(say_hello, "Мир!");

th.join();

return 0;

}

 

 Особенности класса «std::thread»:

  • его нельзя копировать, но можно перемещать и присваивать другим объектам, которые не имеют связи с другими потоками;

  • у каждого потока должен быть свой идентификатор, который возможно узнать, применив метод «get_id»;

  • можно использовать статический метод «hardware_concurrency», возвращающий количество параллельных потоков;

  • можно использовать статические методы для «усыпления» потоков: «sleep_for» или «sleep_until»;

  • при необходимости можно передать управление другим потокам при помощи функции «yield»;

  • класс может вызывать объекты трех видов: указатель на функцию, функциональный объект, лямбда-выражение.

 

Запускаем новый поток с применением указателя на функцию следующим образом:

void foo(parameters)

{

    //описываем действие, которое необходимо сделать

}

std::thread thread_object(foo, parameters)

 

Запускаем новый поток с применением функционального объекта следующим образом:

// Для начала необходимо определить класс объекта функции

class fn_obj_class {

void operator() (parameters)

{

//Описываем действие, которое необходимо выполнить

}

}

//создаем объект потока

std::thread thread_object(fn_class_obj(), parameters)

Запускаем новый поток с применением лямбда-выражения следующим образом:

//Для начала необходимо определить лямбда-выражение

auto x = [] (parameters) {

//Описываем действия, которые необходимо выполнить

};

//необходимо передать «х» и его параметры в конструктор объекта

std:: thread thread_object (x, parameters);

 

Заключение

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

Схожие статьи

Алгоритмы и структуры данных С. Объясняем сложное простыми словами
Другое

Алгоритмы и структуры данных С. Объясняем сложное простыми словами

Лучшие программы для тренировки скорости печати на клавиатуре
Другое

Лучшие программы для тренировки скорости печати на клавиатуре

Самые большие числа и какое число идет после гугла
Другое

Самые большие числа и какое число идет после гугла

Текстуры и проецирование цвета
Другое

Текстуры и проецирование цвета