![]() |
|
Модераторы: xvr |
![]()
|
|
| mephis |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
Здравствуйте. нужно написать программу, которая лезет в БД, проверяет значения в ячейках и запускает таймер (время = значение ячейки) в отдельном потоке. потоки должны выполняться параллельно.
в таком варианте потоки запускаются и отрабатывают по очереди. если закоментить pthread_join, то таймеры не запускаются. как решить проблему? |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 16 Всего: 110 |
убери pthread_join() и используй барьер.
Добавлено через 45 секунд после while() |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 20 Всего: 223 |
Передавать в pthread_create this в качестве параметра для создаваемого thread'а - плохая идейя. У вас все thread'ы передерутся за этот this, т.к. нет никакой гарантии, что Deamon::threadFunction прочтет данные оттуда раньше, чем цикл while в Deamon::connectDB их перезапишет для следующего потока.
Во вторых - надеюсь, что вызов threadDmn->curTimer.at(threadDmn->number).startTimer(); блокируется, иначе у вас все запущенные потоки немедленно завершаться, до наступления заданного timeout'а (а если так и задумывалось, то зачем вообще нужны потоки?) |
|||
|
||||
| mephis |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
можно подробнее объяснить, как это нужно делать? |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 16 Всего: 110 |
гуглить:
pthread_barrier_init() pthread_barrier_wait() pthread_barrier_destroy() |
|||
|
||||
| mephis |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
переделал программу, используя барьеры. в дебаг режиме всё работает как часы, а вот в обычном - проблема. как уже заметил товарищ xvr, у меня number инкрементируется раньше, чем заканчивает выполнение pthread_create, поэтому в последней итерации я выхожу за пределы массива myThread и ловлю сегфолт. посоветуйте, пожалуйста, как эту проблему решить. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 16 Всего: 110 |
для начала, pthread_barrier_wait() перемести в Deamon::connectDB() после цикла.
|
|||
|
||||
| mephis |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
когда я перемещаю его под while(), таймеры вообще не запускаются. извиняюсь за криворукость, не туда вставлял. работает. Это сообщение отредактировал(а) mephis - 8.5.2012, 13:42 |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 16 Всего: 110 |
||||
|
||||
| mephis |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
нет. как я понимаю, пока выполняется pthread_create, происходит инкремент number и в функцию попадает уже увеличенное на 1 значение . я обошел это таким способом:
но я опасаюсь, что на менее/более быстрых процессорах это всё полетит к чертям и будет путаница. поэтому хочу найти нормальное решение проблемы. |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 16 Всего: 110 |
что-то не въезжаю...
твой код расщитан на пять потоков. т.е. ты уверен что в БД всегда пять записей? |
|||
|
||||
| mephis |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
нет, там могут быть от 1 до 5 записей. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 16 Всего: 110 |
т.е. не больше пяти? никогда?
Добавлено через 4 минуты и 21 секунду а number тебе в какие моменты инкрементировать нужно? |
|||
|
||||
| mephis |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
честно говоря, в базе может быть сколько угодно записей и на каждую запись требуется таймер. но пока я делаю фиксированную длину. поэтому сейчас да - не больше 5. Добавлено через 50 секунд
number инкрементировать нужно после того, как отработал pthread_create. |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 16 Всего: 110 |
сейчас оно так и есть. не понимаю, в чем проблема? |
|||
|
||||
| mephis |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
да, оно так и есть. проблема в том, что, когда использую number в threadFunction, он уже приходит не со своим значением, а number+1. то есть получается у меня так, что number каким-то образом инкрементируется раньше, чем нужно и в threadFunction он уже попадает инкрементированным. поэтому на первой итерации у меня стартует не 0-й таймер, а 1-й. на последней итерации получаю сегфолт, т.к. number на 1 выше, чем моё количество таймеров. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 16 Всего: 110 |
тогда тебе нужно не -
а - тогда когда запустилась функция потока. и почему number не инкрементировать в функции потока? |
|||
|
||||
| mephis |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
пробовал раньше, до исправления с барьером, ничего не менялось. приду с работы, попробую сделать так ещё раз. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 16 Всего: 110 |
в функцию потока передай указатель на number. в ней, разыменовываешь его, и инкрементируешь.
|
|||
|
||||
| sergioK1 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 417 Регистрация: 30.1.2011 Репутация: нет Всего: нет |
вот тут
может быть что счетик увеличиваеться до вызова threadFunction, может быть и нет, но это решает OS програмист на это повлиять не может, boostcoder барьер тут не поможет, с передачай указателя да , cчетчик должен быть внутри threadFunction - это просто логичнее, поговорка есть на такой случай , "При правильном дизайне программа пишеться сама " Это сообщение отредактировал(а) sergioK1 - 9.5.2012, 08:07 |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 20 Всего: 223 |
Вынесите number из Deamon вообще, и передавайте его отдельной структурой (вместе с this) на куче:
Тогда барьеры не нужны |
|||
|
||||
| mephis |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
так и сделал. всё работает. всем спасибо за помощь. |
||||
|
|||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 20 Всего: 223 |
Кстати, если у вас это не учебная задача, и критично быстродействие при запуске thread'ов, то у этого подхода есть маленький недостаток. На каждое создание thread'а будет вызванна пара new/delete. Этого можно избежать заранее выделив массив из структур Data и передавая в создаваемый thread указатели на элементы этого массива по очереди (только надо внимательно следить за индексом элемента, что бы он не вышел за границы массива и не наложился на все еще используемые элементы) |
|||
|
||||
| mephis |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.2.2012 Репутация: нет Всего: нет |
задача не учебная. и если будут присутствовать 1000 и больше thread-ов, то проблемы быстродействия сразу скажутся. программа должна работать в реальном времени с постоянно меняющимися данными в БД, поэтому каждое промедление будет критично и может привести к сбою. благодарю за замечание, я это обязательно учту. |
|||
|
||||
| sergioK1 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 417 Регистрация: 30.1.2011 Репутация: нет Всего: нет |
1000 средов на одной машине ? так может подумать о threadPool |
|||
|
||||
![]()
|
| Правила форума "С/С++: Программирование под Unix/Linux" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |