Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/32: Рейтинг темы: голосов - 32, средняя оценка - 4.72
4 / 4 / 0
Регистрация: 21.02.2012
Сообщений: 7

Многопоточность. Взаимодействие потоков.

21.02.2012, 23:00. Показов 6651. Ответов 29
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствие.
Возникла задача напрограммировать многопоточную программу.
Вот нарисовал приблизительно как оно должно работать:
Thread 1 работает как-то так:

C++
1
2
3
4
5
6
while(true){
 /* опрос девайса, если есть новые события, то они отправляются в FIFO */
 /* Если был запрос от Thread2(ну не обязательно от него), то идёт команда на девайс установить OUT0 в 1*/
 /* Если был запрос от Thread3(ну не обязательно от него), то идёт нужный запрос на девайс, в Thread3 возвращается результат */
 /* задержка */
}
Thread2 обрабатывает FIFO и ещё что-нибудь и когда надо оставляет запрос на установку OUT0 в 1 и продолжает работу не дожидаясь обработки запроса.
Thread3 взаимодействует с пользователем и у него внутри есть функции(для работы с Thread1) типа
C++
1
2
3
4
5
6
7
bool get_in_state(unsigned int pinid){
  /* отправляем в Thread1 запрос(с аргументом) на выполнение и дожидаемся результата*/
  return state;
}
void set_out_state(unsigned int pinid, bool val){
  /* отправляем в Thread1 запрос(с аргументами) и, желательно, дождаться окончания*/
}
Идеально было-бы, если-бы get_in_state() и set_out_state() могли выдавать исключения, если это явно запрошено Thread1
Название: ba18db6dcc6e73e53bd8fc670a71e969.jpg
Просмотров: 621

Размер: 6.1 Кб

Теперь вопросы:
  1. Что использовать для FIFO(причём с ним работают 2 потока)? {STL Queue и pthread_mutex_t?}
  2. Как реализовать запрос от Thread2 к Thread1? { Семафор? }
  3. Как реализовать взаимодействие Thread3 с Thread2? {два мьютекса и несколько переменных для аргументов и результата - приходит в голову но, мне кажется, это слишком кривое решение.}
  4. Да и вообще, как правильно реализовывать треды? {ptread_create?}
  5. Может одна переменная быть общей(например, устанавливается в одном треде, а читается и обнуляется в другом)?

Заранее спасибо за ответы.

ps Заранее извиняюсь за криво поставленные вопросы, с параллельными потоками сталкиваюсь почти впервые, да и C++ я знаю довольно почти никак(на уровне "да это-же Си с классами и throw").
pps
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.02.2012, 23:00
Ответы с готовыми решениями:

Многопоточность. Замедление/уменьшение потоков
Добрый день. написал Аккаунт менеджер для некого сайта, который выполняет действия с аккаунтом. Для оперирования с большим количеством...

Многопоточность. Создание потоков в цикле
Добрый день! Пытаюсь создать в цикле потоки с разными параметрами, вызываю каждый раз одну и ту же функцию. Каждый раз в параметре...

Многопоточность и синхронизация потоков (VS 2012)
код игры тетрис написан на С++/CLI. Стандартное падение фигур и их обрисовка происходит отлично ( реализована в pictureBox), но обработка...

29
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
22.02.2012, 01:34
при использовании asio задача реализуется банально до невозможного. и не единого потока
хотя по правде сказать, я и так не уверен в надобности трех потоков. ну один...и то под сомнением...
0
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
22.02.2012, 03:54
parus, правильнее начать прогить и по ходу, если возникают проблемы, задавать вопросы здесь. А не так, почитал чего-то, собрал кучу всего, что не понимаешь, и взвалил в одну тему.
По вашим вопросам видно что вы даже не пытались разобраться, хотя большая часть ответов есть в википедии.
Для взаимодействия потоков используются семафоры и мьютексы.
В мьютекс оборачиваются общие объекты (глобальные переменные, массивы и т.д.), которые могут изменять несколько потоков.
Делается это в каждом потоке так:
C++
1
2
3
4
5
6
7
8
9
 pthread_mutex_lock(&mut);
 //тут что-то делаем к примеру с переменной а:
 a=10;
 a*=n+time();
 while(...) {
   sleep(1);
   a*=n+time()%10;
 }
 pthread_mutex_unlock(&mut);
И пока мы это делаем, ниодин поток не должен вмешиваться и менять значение a.
В итоге получится так, что два потока не могут одновременно записывать что-то в одну область памяти, или например изменить адрес указателей и т.д.
Ну с семафором всё просто, в одном потоке он увеличивается на 1 вызовом
C++
1
sem_post(&sem);
В другом уменьшается также на единицу вызовом
C++
1
sem_wait(&sem);
Если sem==0, то sem_wait блокируется до тех пор, пока другой поток не сделает вызов sem_post и не увеличит значение до >0.
Семафоры используются для организации очереди обработки.
1
4 / 4 / 0
Регистрация: 21.02.2012
Сообщений: 7
22.02.2012, 13:12  [ТС]
Цитата Сообщение от niXman Посмотреть сообщение
при использовании asio задача реализуется банально до невозможного. и не единого потока
хотя по правде сказать, я и так не уверен в надобности трех потоков. ну один...и то под сомнением...
Если вы про асинхронные чтение/запись, то, я думаю, это мне только позволит наделать больше ошибок.
Да и тут задача в упрощённом виде, т.ч. потоки нужны.

Union Ну я начал, сделал работу с девайсом(с таймаутами и исключениями). А дальше с потоками непонятно. Ничего.

Спасибо, что-то стало понятней. Осталось приблизительно два вопроса:
0) Память, выделенная приложению никак не разделяется на память, выделенную потоку и единственная проблема общего доступа - это вытеснение потока во время работы с общей переменной?
1) И всё-таки, как правильно сделать(хотя-бы как это правильно называется) такое взаимодействие между Thread3 и Thread2?
0
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
22.02.2012, 17:55
По поводу первого вопроса, правильнее сказать не "вытеснение потока во время работы с общей переменной", а блокировка всех потоков, которые хотят обратиться к общей памяти, когда какой-то один из потоков к ней обращается, на время этого самого обращения.
Второй вопрос не понял, "такое взаимодействие" - это какое? Я вроде расписал 2 используемых принципа. Если не во всех, то в большинстве случаев их достаточно, в т.ч. и в вашей задаче.
Однако niXman прав, тут достаточно одного потока...
А подключать доп. потоки нужно только тогда, когда процессор не справляется с задачами в одном.
Я правда ниразу не юзал asio, предпочитаю всё делать вручную, но судя по обсуждениям эту вещь стоит освоить.
0
4 / 4 / 0
Регистрация: 21.02.2012
Сообщений: 7
22.02.2012, 18:08  [ТС]
Цитата Сообщение от Union Посмотреть сообщение
0)Второй вопрос не понял, "такое взаимодействие" - это какое? Я вроде расписал 2 используемых принципа. Если не во всех, то в большинстве случаев их достаточно, в т.ч. и в вашей задаче.
1)А подключать доп. потоки нужно только тогда, когда процессор не справляется с задачами в одном.
0)Я не могу внятно объяснить, как это делается, ну как-то так:

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
volatile bool func_flag=false;
volatile int arg1, arg2;
volatile int ret;
 
/* второй поток */
void thread_loop(){
  while(true){
    /* делаем свои дела*/
    if (func_flag){
       ret = arg1+arg2;//Т.е. выполняем операцию с двумя аргументами и выдаём результат.
       //Разумеется, операция не просто арифметическая, и должна выполняться именно в этом потоке
       func_flag = false;
    }
    sleep(2);
  }
}
 
/* а снаружи(из первого потока), я вызываю: */
int func(int a1, int a2){
 arg1=a1;
 arg2=a2;
 func_flag=true;
 while(func_flag);
 return ret;
}
Этот код, разумеется, неправильный. Ну по нему вы смогли понять что я хочу?

1) Не буду спорить, ибо почти ничего не понимаю. Но многопоточность ещё упрощает разработку. Иначе зачем были-бы RTOS для микроконтроллеров, ведь они потребляют ресурсы, которых на МК и так немного.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
22.02.2012, 18:44
Цитата Сообщение от Union Посмотреть сообщение
Для взаимодействия потоков используются семафоры и мьютексы
Цитата Сообщение от Union Посмотреть сообщение
В мьютекс оборачиваются общие объекты
Цитата Сообщение от Union Посмотреть сообщение
Делается это в каждом потоке так
Цитата Сообщение от Union Посмотреть сообщение
два потока
Цитата Сообщение от Union Посмотреть сообщение
с семафором всё просто
всего один вопрос: зачем городить этот говнокод? чтоб на говнокод.ру его однажды встретить?



Цитата Сообщение от parus Посмотреть сообщение
асинхронные чтение/запись, то, я думаю, это мне только позволит наделать больше ошибок.
судя по уровню твоих вопросов, многопоточное программирование для тебя не проще.


Цитата Сообщение от parus Посмотреть сообщение
тут задача в упрощённом виде, т.ч. потоки нужны.
я не телепат. постановка задачи таки не требует наличия хоть одного потока.
0
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
22.02.2012, 19:13
niXman, я не приводил говнокод, я описал как организуется многопоточность. А дальше, с использованием этих фукнций, прогер может написать как говнокод, так и нормальный, компактный, быстрый код... А если постараться, то можно написать даже лучше, чем с использованием asio.
Поэтому, на мой взгляд, товарищу parus сначала следует освоить именно то, что я написал в третьем посте темы. Потому как это основы. А дальше улучшать свой код, изучать новые методы, технологии и т.д.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
22.02.2012, 20:43
Цитата Сообщение от Union Посмотреть сообщение
я не приводил говнокод
нет. ты порекомендовал заняться его написанием.

Цитата Сообщение от Union Посмотреть сообщение
лучше, чем с использованием asio.
пример "лучшести" пожалуйста
0
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
22.02.2012, 21:11
Мне кажется очевидно что это не требует доказательств. Такой вывод можно сделать следуя из назначения asio и назначения pthread. Вы считаете что asio более универсальна, нежеле чем pthread?
Очень часто сетевые приложения занимаются обработкой не только сетевых задач. asio ориентирована только на решение сетевых задач.
Используя pthread можно самому организовать любую структуру приложения.

Добавлено через 3 минуты
И да, я говорил что с использованием pthread в специфических случаях можно составить приложение с лучшей структурой, однако часто это не оправдано и если судить вообще, то я с вами не спорю, надо использовать asio и не париться.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
22.02.2012, 21:24
Цитата Сообщение от Union Посмотреть сообщение
очевидно
очевидно, что?

Добавлено через 2 минуты
Цитата Сообщение от Union Посмотреть сообщение
из назначения asio и назначения pthread
некорректное сравнение. у обоих разное назначение.

Цитата Сообщение от Union Посмотреть сообщение
asio более универсальна, нежеле чем pthread?
читать выше.

Цитата Сообщение от Union Посмотреть сообщение
asio ориентирована только на решение сетевых задач.
ты под веществами? оО

Цитата Сообщение от Union Посмотреть сообщение
можно самому
зОчем? оО
0
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
22.02.2012, 21:25
Я про это:
Цитата Сообщение от niXman Посмотреть сообщение
Цитата Сообщение от Union Посмотреть сообщение
А если постараться, то можно написать даже лучше, чем с использованием asio.
пример "лучшести" пожалуйста
Больше не буду с вами спорить, вы фанат asio, т.ч. это бестолку. Каждый сам для себя сделает правильный выбор.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
22.02.2012, 21:30
Цитата Сообщение от Union Посмотреть сообщение
не буду с вами спорить
не нужно рекомендовать форумчанам городить говнокод, когда есть способ реализовать задачу более естественно и качественно во всех отношениях.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
23.02.2012, 10:48
да, да, этот самый говнокод уже за Вас нагородили авторы boost
0
 Аватар для Union
17 / 17 / 0
Регистрация: 16.08.2010
Сообщений: 252
24.02.2012, 00:13
ВО, g_u_e_s_t правильно, это я и имел ввиду. asio ведь тоже работает на pthread, т.ч. если уж довести слова niXman'а, то asio нагороженный говноко... )))
(PS эт я шучу, можно не отвечать)
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
24.02.2012, 01:29
Цитата Сообщение от Union Посмотреть сообщение
asio ведь тоже работает на pthread
никак понять не могу, откуда у человеческих особей упорное стремление выставлять себя глупцами, мягко говоря?.. %)
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.02.2012, 10:08
niXman, у Вас наверное какой-то особенный Boost.asio без нитей и _глобального_ (вот где какашка на мой взгляд прячется) мутекса вокруг пуллера?
Вот объясните мне глупому, в чем прелесть даунгрейта бсдешного kqueue до epoll, я понимаю, что авторам boost (равно как и eventlib и большенства прочих событийных тулкитов) это удобно, но в чем мой профит от лишнего сискола на каждое событие?
ИМХО любое универсальное решение, априори сливает разработанному под конкретную задачу.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
24.02.2012, 10:25
зачем asio мьютексы? оО

остального не понял.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.02.2012, 12:03
Цитата Сообщение от niXman Посмотреть сообщение
зачем asio мьютексы? оО
*facepalm*
А Вы попробуйте шаблоны усиленно рекламируемого Вами boost почитать, может догадаетесь/поймете как и зачем asio защищает epoll_wait мутексом.
Цитата Сообщение от niXman Посмотреть сообщение
остального не понял.
Поясняю. Имеем 2 механизма пулинга файловых дескрипоров и прочих объектов ОС. epoll в линукс и kqueue в BSD системах. Для добавления/удаления/изменения объекта линуксячий epoll требует вызова epoll_ctl() на каждый изменяемый объект, kqueue позволяет вносить изменения оптом. Можно я буду считать не использование такой возможности (до минус 100 сисколов на цикл под нагрузкой) говнокодом? Спасибо.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
24.02.2012, 12:08
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
А Вы попробуйте шаблоны усиленно рекламируемого Вами boost почитать, может догадаетесь/поймете как и зачем asio защищает epoll_wait мутексом.
до таких "глубин" я не читал коды asio. сориентируйте на файл:строка


Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Для добавления/удаления/изменения объекта линуксячий epoll требует вызова epoll_ctl() на каждый изменяемый объект, kqueue позволяет вносить изменения оптом.
сориентируйте на файл:строка
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.02.2012, 12:08
Помогаю со студенческими работами здесь

Многопоточность - правильное завершение потоков
Вот первый вопрос: 1) Как завершить заданное количество потоков. Pars - это потомок класса TThread Pars *Thr; - задано глобально. ...

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

Взаимодействие потоков.
Недавно начал изучать C# и столкнулся с такой проблемой в лабе. "Недопустимая операция в нескольких потоках: попытка доступа к элементу...

Многопоточность - как создать динамический массив потоков
Привет всем:) Вот решил заняться многопоточность и,как и у всех,возникли проблемы. 1) как создать динамический массив потоков? Unit1 ...

Взаимодействие потоков и формы
Я что-то смотрел читал и тдп. Так и не понял как можно реализовывать норм выполнение функций в других потоках что бы эта ***** форма не...


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

Или воспользуйтесь поиском по форуму:
20
Закрытая тема Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru