Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.85/34: Рейтинг темы: голосов - 34, средняя оценка - 4.85
10 / 30 / 1
Регистрация: 19.11.2017
Сообщений: 405
1

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

21.11.2017, 11:59. Показов 6803. Ответов 66
Метки нет (Все метки)

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

А вот что касается многопоточности непонятно следующее - зачем она нужна? Какие преимущества многопоточной программы перед обычной программой?

Как я понял, увеличивается скорость выполнения исходного кода программы.

Дальше столкнулся ещё с таким:

Допустим у нас есть программа(процесс), он разделен на 2 потока. Каким образом команды будут распределяться между этими двумя потоками? Произвольным или заданным мной? Например есть такие команды:

int average;
int variable;
CppStudio objMessage;
objMessage.message();
system("pause");
return 0;
Как эти команды будут распределены между двумя потоками? И может ли быть такое, что первый поток выполнит:

int average;
int variable;
CppStudio objMessage;
А второй поток выполнит:

int average;
int variable;
CppStudio objMessage;
objMessage.message();
system("pause");
То есть произойдет конкуренция за команды? Или второй потокок может выполнить только команды, которые не выполнил 1 поток:
objMessage.message();
system("pause");

Спасибо.
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.11.2017, 11:59
Ответы с готовыми решениями:

Многопоточность в C++ и C++11
как я понял, многопоточность появилась в С++11 cтандарте. Почитал что его вроде как visual studio...

Многопоточность
Есть задание: Написать и протестировать функцию, которая находит в массиве минимальный по модулю...

Многопоточность С++
Добрый вечер! написал вот такую программку. std::vector<std::thread> threads;...

Многопоточность c++
Добрый день! Я только начинаю изучать многозадачность в c++ и у меня возник вопрос о том как...

66
433 / 425 / 159
Регистрация: 21.05.2016
Сообщений: 1,338
21.11.2017, 12:25 2
Распределение задач по потокам полностью лежит на разработчике
1
10 / 30 / 1
Регистрация: 19.11.2017
Сообщений: 405
21.11.2017, 12:29  [ТС] 3
Теперь непонятно следующее - команды программы должны выполняться последовательно в том порядке, котором они написаны программистом, но если разбить программу на потоки, то получается что команды могут выполняться в произвольном порядке, из-за чего программа становится другой.

Еще вопрос - может в программе быть 100 потоков или более?
0
Эксперт С++
8426 / 4099 / 894
Регистрация: 15.11.2014
Сообщений: 9,212
21.11.2017, 12:34 4
Цитата Сообщение от mikello Посмотреть сообщение
Как эти команды будут распределены между двумя потоками?
вы демонстрируете полное не понимание сабжа.
причем, очевидно, что вы даже не пытались
почитать какой нибудь букварь по теме.

все ваши домыслы не имеют ничего общего с реальностью.

хотите, что бы вам сюда скопипастили материал из книжки?

что бы развеять ваши наивные домыслы?
1
3348 / 1926 / 368
Регистрация: 09.09.2017
Сообщений: 7,799
21.11.2017, 12:35 5
Многозадачность это свойство операционной системы разделять время процессоров (ядер) между процессами чтобы каждый из них думал что выполняется непрерывно и одновременно с другими.
Многопоточность это свойство программы использовать многозадачность системы. То есть запускать внутри одного пространства процесса несколько относительно независимых потоков, выполняющихся одновременно. Например, в серверной программе выделить по потоку для каждого клиента, чтобы не отвлекать на это ресурсы основного потока. Или просто чтобы задействовать несколько ядер вместо одного.
Многопоточность надо реализовывать самостоятельно вызовами функций создания потока (или процесса, разница невелика), синхронизацией доступа к памяти, слежением и прочим. Это функции (pthread_create + pthread_join) / (CreateThread + WaitForSingleObject + CloseHandle).
Отличие многопоточной программы от многопроцессной в том что потоки располагаются в общем пространстве, у них общая память (с общим ограничением на 4 ГБ на 32-разрядных системах) и если выскакивает исключение в каком-то потоке, это может поломать всю программу.
В многопроцессных же программах создаются относительно независимые процессы в собственных адресных пространствах, почти как отдельные программы. Но у них сохраняется иерархия и родитель может узнать о состоянии порожденных процессов, послать им сообщения и т.д. Для создания новых процессов используется fork(). Как это делается в Windows не уверен, вроде ShellExecute, но это все-таки немного другое.
1
1 / 1 / 0
Регистрация: 21.11.2017
Сообщений: 24
21.11.2017, 12:35 6
Почитайте про std::thread - это и есть часть STL для работы с потоками. В вашем коде нет упоминания многопоточности, вся логика распределения вызовов ложится на вас.

то получается что команды могут выполняться в произвольном порядке, из-за чего программа становится другой.
Именно так, main и остальные потоки созданные вами будут выполняться параллельно в случае вызова detach на каждом из них.

Еще вопрос - может в программе быть 100 потоков или более?
Да может, только в этом не очень много смысла, с точки зрения ресурсов. Я бы использовал по количеству логических ядер процессора - это число можно получить из вызова std::thread::hardware_concurrency
1
433 / 425 / 159
Регистрация: 21.05.2016
Сообщений: 1,338
21.11.2017, 12:36 7
Цитата Сообщение от mikello Посмотреть сообщение
Теперь непонятно следующее - команды программы должны выполняться последовательно в том порядке, котором они написаны программистом, но если разбить программу на потоки, то получается что команды могут выполняться в произвольном порядке, из-за чего программа становится другой.
Точно так. Поэтому требуется синхронизация потоков

Цитата Сообщение от mikello Посмотреть сообщение
Еще вопрос - может в программе быть 100 потоков или более?
Да. Зависит от объема памяти
1
3348 / 1926 / 368
Регистрация: 09.09.2017
Сообщений: 7,799
21.11.2017, 12:39 8
Цитата Сообщение от mikello Посмотреть сообщение
но если разбить программу на потоки, то получается что команды могут выполняться в произвольном порядке, из-за чего программа становится другой.
Нет. В каждом потоке команды выполняются все также последовательно. А о том какие команды будет выполнять данных поток, заботится программист.
Цитата Сообщение от mikello Посмотреть сообщение
Еще вопрос - может в программе быть 100 потоков или более?
Зависит от ограничений операционной системы. Более 100 процессов запросто, а с потоками сложнее, но вроде обычное ограничение более 30000. Не уверен, надо смотреть документацию.

Добавлено через 1 минуту
Цитата Сообщение от mrAndersen7 Посмотреть сообщение
Да может, только в этом не очень много смысла, с точки зрения ресурсов.
Я уже приводил пример с "поток на клиента". При этом поток большую часть времени спит и не мешает
1
Эксперт С++
8426 / 4099 / 894
Регистрация: 15.11.2014
Сообщений: 9,212
21.11.2017, 12:39 9
Цитата Сообщение от oldnewyear Посмотреть сообщение
Да. Зависит от объема памяти
не корректный ответ

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Зависит от ограничений операционной системы.
корректный ответ.
2
433 / 425 / 159
Регистрация: 21.05.2016
Сообщений: 1,338
21.11.2017, 12:41 10
Цитата Сообщение от hoggy Посмотреть сообщение
не корректный ответ
корректный ответ.
Вы как всегда всё расставили по своим местам
0
3348 / 1926 / 368
Регистрация: 09.09.2017
Сообщений: 7,799
21.11.2017, 12:58 11
Вот пример многопоточной программы
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
 
void* thread1(void* arg){ //алгоритм первого дочернего потока
  for(int i=0;i<10;i++){
    printf("Thread1: %i/10\n",i);
    usleep(100000);
  }
}
void* thread2(void* arg){ //алгоритм второго дочернего потока
  printf("thread2------------------------------\n");
  usleep(500000);
  printf("thread2------------------------------\n");
  usleep(500000);
  printf("thread2------------------------------\n");
  usleep(500000);
  printf("thread2------------------------------\n");
}
 
int main(){ //запуск основного процесса, он же основной поток
  pthread_t t1, t2;
  pthread_create(&t1, (const pthread_attr_t *)NULL, thread1, NULL);  //запуск первого дочернего потока (2-й поток в процессе)
  pthread_create(&t2, (const pthread_attr_t *)NULL, thread2, NULL); //запуск второго дочернего потока (3-й поток в процессе)
  printf("===MAIN============================\n");
  pthread_join(t1, NULL); //ожидаем завершения первого дочернего потока
  pthread_join(t2, NULL); //ожидаем завершения второго дочернего потока
}
Компилировать с опцией -pthread
Как видно, все три потока линейны и не пересекаются. В то же время выполняются они одновременно
1
433 / 425 / 159
Регистрация: 21.05.2016
Сообщений: 1,338
21.11.2017, 13:09 12
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Как видно, все три потока линейны и не пересекаются. В то же время выполняются они одновременно
Нет гарантии, что они будут выполняться одновременно
0
10 / 30 / 1
Регистрация: 19.11.2017
Сообщений: 405
21.11.2017, 13:31  [ТС] 13
COKPOWEHEU,
Например, в серверной программе выделить по потоку для каждого клиента, чтобы не отвлекать на это ресурсы основного потока.
А если у нас 1000000 клиентов ?
0
Любитель чаепитий
3587 / 1687 / 519
Регистрация: 24.08.2014
Сообщений: 5,705
Записей в блоге: 1
21.11.2017, 13:36 14
Цитата Сообщение от mikello Посмотреть сообщение
А если у нас 1000000 клиентов ?
в таких случаях, обычно, серверов тоже много.
и вместе с ними идут сервера балансировки нагрузки.
0
10 / 30 / 1
Регистрация: 19.11.2017
Сообщений: 405
21.11.2017, 14:14  [ТС] 15
COKPOWEHEU,
Например, в серверной программе выделить по потоку для каждого клиента, чтобы не отвлекать на это ресурсы основного потока.
А если у нас очень много клиентов, и сервер может обратиться к клиенту №10000 (например) только через достаточно немалое время, что нас не устраивает (т.е. поток будет выполнен через немалое время). Как быть в такой ситуации?
0
303 / 215 / 74
Регистрация: 23.05.2011
Сообщений: 971
21.11.2017, 14:21 16
Обычно там делают очередь задач, в которую складывают запросы, а несколько потоков берут задачи из очереди и выполняют.
0
10 / 30 / 1
Регистрация: 19.11.2017
Сообщений: 405
21.11.2017, 14:31  [ТС] 17
Обычно там делают очередь задач, в которую складывают запросы, а несколько потоков берут задачи из очереди и выполняют.
я имел в виду, если у нас есть допустим 10000 потоков, и выполняются они как бы одновременно ( то есть сначала 1 поток чуть-чуть, затем 2, и так далее по кругу) то пока очередь дойдет до потока10000 может пройти достаточно длительный промежуток времени.Как этого избежать?

Ваш пример, честно говоря, не очень понял...
0
3348 / 1926 / 368
Регистрация: 09.09.2017
Сообщений: 7,799
21.11.2017, 14:50 18
Цитата Сообщение от oldnewyear Посмотреть сообщение
Нет гарантии, что они будут выполняться одновременно
usleep переключает задачу, так что почти наверняка будут одновременно. В любом случае ТСу пока рано лезть в тонкости синхронизации
Цитата Сообщение от mikello Посмотреть сообщение
А если у нас 1000000 клиентов ?
Насколько я знаю, запускают обычно не потоки а процессы. Чтобы не упираться в потолок количества потоков и для безопасности. Работа по сети в любом случае не гарантирует скорости так что лишние миллисекунды до переключения на нужный поток несущественны.
Встречный вопрос - как это сделать лучше?

Добавлено через 1 минуту
Цитата Сообщение от mikello Посмотреть сообщение
пока очередь дойдет до потока10000 может пройти достаточно длительный промежуток времени.Как этого избежать?
Никак. На практике потоки переключаются достаточно быстро чтобы это не было заметно.

Добавлено через 20 секунд
Цитата Сообщение от mikello Посмотреть сообщение
пока очередь дойдет до потока10000 может пройти достаточно длительный промежуток времени.Как этого избежать?
Никак. На практике потоки переключаются достаточно быстро чтобы это не было заметно.
1
303 / 215 / 74
Регистрация: 23.05.2011
Сообщений: 971
21.11.2017, 15:25 19
Понимаете, оптимальное число потоков — это количество ядер процессора. Иногда ещё рекомендуют количество ядер -1.

То, что я описал, работает примерно так (псевдокод):

Код
class command{
  void do(){} // собственно обработка запроса тут
}

queue<command> container;
mutex mutex; // это так называемый мьютекс. 
void add_command(command c)
{
   mutex.lock(); // одновременно в промежуток кода между lock() и unlock() может залезть только один поток
   container.push_back(c);
   mutex.unlock();
}


volatile bool continue_threads;
command get_command()
{
   while(!container.size() && continue_threads)
   {
       sleep(50); // поток спит, если контейнер пустой.
    }
   mutex.lock();
   if (container.size())
        res = container.pop();
   else
        res = empty_command();
   mutex.unlock();
   return res;
}


// А это то, что делают потоки.
void * thread_func()
{
    while(continue_threads)
    {
         get_command().do();
    }
}

// в коде где-то создают несколько потоков, которые бесконечно разгребают задачи, которые в основном потоке добавляются.

continue_threads = true;
for(int i < N)
threads[i] = create_thread(&thread_func);

.....
// при остановке сервера:
continue_threads = false;
for(int i < N)
threads[i].join();
0
10 / 30 / 1
Регистрация: 19.11.2017
Сообщений: 405
21.11.2017, 15:41  [ТС] 20
Иногда ещё рекомендуют количество ядер -1
-1? Не понял. Все остальное вроде бы понятно.

Насколько я знаю, запускают обычно не потоки а процессы.
А как запустить несколько процессов? Это имеется в виду, что запустить несколько экземпляров программы?

Ещё такой вопрос - в некоторых программах для работы с интернетом, есть такое понятие как потоки, но это какие-то другие потоки. Например, в программе брутфорса почты можно выставлять 100, 200 , 300 и т.д. потоков. Что это за потоки, и как они реализуются?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.11.2017, 15:41

Многопоточность
Не особо понимаю мнопоточность в с++. Есть задание типа.... Сделать программу, иммитирующую работу...

Многопоточность
При добавлении больше 10000 элементов в таблицу на форму форма зависает, как это исправить?...

Многопоточность
Здраствуйте! Объясните пожалуйста понятными словами что такое многопоточность и для чего она нужна?

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.