|
|
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Суть проблемы. Программа Сервер-приложений валится. (ошибка сегментирования). Qt + Linux. Раньше валился чаще - теперь раз в сутки. Часть проблем я нашёл приведя программу к стандарту С++ явным образом, а не полагаясь на то, что компилятор должен чего-то сам сделать автоматически. Таким образом ошибка "блуждающая" локализовалась - я её сумел обнаружить и исправить. (об этом я писал, тут, на форуме). Теперь наставил в контрольных точках вывод действий сервера в консоль cout << "бла-бла-бла" << endl; Код: plaintext 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. 30. 31. 32. 33. 34. 35. Смотрю в консоль и вижу > newConnection begin > newConnection end > thread run begin > thread run while > Ошибка сегментирования Задним умом понимаю до MySocket::slotReadClient begin он не дошёл, а больше программа ничего не делает. После старта потока она должна принять запрос клиента. Спрашивается - а В ГДЕ она вывалилась? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2007, 17:32 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Ээээ логирование канешна карашо, а где код ??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2007, 17:37 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Так другой поток, может, валит? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2007, 17:42 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Какой именно? Думаю, для начала интересен этот Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2007, 17:46 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
ZmeisheКакой именно? Думаю, для начала интересен этот Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Не знаю, что у тебя за операционка, но у меня (ASP10) такая конструкция запросто может систему подвесить. Поток у тебя, конечно, оригинальный. Зачем тебе пустой поток? Этим кодом ты ничего не показал. Вызов каких-то твоих функций. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2007, 17:52 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
авторНе знаю, что у тебя за операционка, но у меня (ASP10) такая конструкция запросто может систему подвесить. Поток у тебя, конечно, оригинальный. Зачем тебе пустой поток? Этим кодом ты ничего не показал. Вызов каких-то твоих функций. Suse не виснет, Fedora не виснет, ASP не проверял. Опишу свою сакральную мысль, а ВЫ раскритикуйте. SoketServer слушает порт и ждёт какого-нибудь клиента На появление клиента создаёт обект класса - поток В потоке создаётся объект класса - клиентский сокет В сокете объект класса - модуль данных Не знаю насколько это логично, но без потока тяжёлый SQL запрос ждали все клиенты - теперь не ждут. Делал по другому - создавал клиентский сокет не в потоке - тормоза. Подскажите другую схему. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2007, 18:02 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Zmeishe...Смотрю в консоль и вижу > newConnection begin > newConnection end > thread run begin > thread run while > Ошибка сегментирования ... предлагаю начать с грамотного подъёма ниток... задайтесь вопросом - а нахрен подымать нитку, если Вампох(простите) пофигу её судьба ? поднялась, не поднялась - а, летим дальше...Предлагаю нафик не подымать - Вам же ВСЁ РАВНО !!! Или по другому - на лицо типичная ошибка, которая будет плавающей от нагрузки на Вашу систему (Ваша система будет по РАЗНОМУ работать, в зависимости от нагрузки - что в принцепе бред..опустим конэшно самоподстраивающиеся алгоритмы - не о них речь...)... предполагаю, что когда решите этот вопрос - Ваша проблема исчезнет...Почему - объясню попозже, если захотите... с уважением (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.04.2007, 18:45 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
где pthread_join() и ваще - кто stop значение устанавливает? надо бы conditional variable если разные потоки ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2007, 00:49 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
ZmeisheКакой именно? Который кладет процесс ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2007, 09:03 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Zmeishe авторНе знаю, что у тебя за операционка, но у меня (ASP10) такая конструкция запросто может систему подвесить. Поток у тебя, конечно, оригинальный. Зачем тебе пустой поток? Этим кодом ты ничего не показал. Вызов каких-то твоих функций. Suse не виснет, Fedora не виснет, ASP не проверял. Опишу свою сакральную мысль, а ВЫ раскритикуйте. SoketServer слушает порт и ждёт какого-нибудь клиента На появление клиента создаёт обект класса - поток В потоке создаётся объект класса - клиентский сокет В сокете объект класса - модуль данных Не знаю насколько это логично, но без потока тяжёлый SQL запрос ждали все клиенты - теперь не ждут. Делал по другому - создавал клиентский сокет не в потоке - тормоза. Подскажите другую схему. По вышеописанной схеме, вместа while (!stop) ;, логично было бы поставить recv(). Ваша схема не понятна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2007, 09:50 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Как опредилить какой поток вызывает крах системы решается путем установки обработчика сигнала. Недавно обсуждали. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2007, 09:52 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
AkhКак опредилить какой поток вызывает крах системы решается путем установки обработчика сигнала. Недавно обсуждали. тынц ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2007, 10:26 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
AkhПо вышеописанной схеме, вместа while (!stop) ;, логично было бы поставить recv(). Ваша схема не понятна. recv() это что и в где? В библиотеке Qt оно есть? Схема рабоче-крестьянская. Проста как топор. Поясню: Многопоточностью начал заниматься недавно - много просто не знаю. Обратился к книгам. Прочитал следущее: Приложение есть процесс - главный процесс, но для операционки просто поток - отдельный поток. Если приложение многопользовательское, то чтобы клиенты не ждали друг друга имеет смысл распараллелить их работу. Лобовое решение - запускать столько серверных приложений сколько клиентов. Но сервер на сокетах начнёт орать, что порт занят. Т.е. каждому клиенту ещё и свой порт выделять. Приличное решение - запускать в отдельной области памяти нечто, каждому клиенту. Многопоточность, типа, и есть то самое решение. Необходимо только унаследовать класс от QThread и перекрыть виртуальную функцию run(). Что я, собственно, и сделал. Вот я в функции потока run() создаю объект, функции которого должны выполняться в отдельной области памяти. Привязываю его к событиям класса QServerSocket и while(!stop); Когда QServerSocket получает сигнал об отключении клиента он для этого sender(), который socket, вызывает stop() соответствующего потока. run() заканчивает работу. Скорость при этом - бешеная. Независимо 1 клиент или 10. Я понимаю, что это топорная работа. И система показывает, что мой процесс жрёт 98.2% CPU. При этом сама система не тормозит. Я переделал всё это иначе. стартую поток только когда от клиента пришли данные и в функции потока run() вызываю свою функцию пересылки SQL запроса к БД и потом формирую ответ клиенту. После чего поток заканчивает работу, до тех пор пока я снова не вызову потоку start() на очередной запрос клиента. Теперь система показывает, что мой процесс жрёт 0.3-0.7% CPU и только во время обращения к БД и отправки ответа клиенту - потом 0.0 %CPU. Это ещё более топорная работа т.к. start() потока занимает какое-то время и клиент получате данные паузами. Если есть DataSet - мастер и у него много DataSet`ов - деталей - каждая деталь открывается с паузами в 1 сек. Это оч. долго. В первом варианте с while(!stop) их вообще не было. На большее, пока, фантации не хватает. Мне собственно нужна грамотная схема связей между MyServerSocket, MySocket, MyThread и чего там в run(), если по уму. Чисто концептуально - мысль понять, остальное сам сделаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2007, 10:39 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Zmeishe AkhПо вышеописанной схеме, вместа while (!stop) ;, логично было бы поставить recv(). Ваша схема не понятна. recv() это что и в где? В библиотеке Qt оно есть? Схема рабоче-крестьянская. Проста как топор. Поясню: ... Понятно. Я считал, что схема клиент-поток. Оказывается задача-поток. Тогда логично было бы сделать вместо while(!stop) ; - синхронное обращение к БД. А у вас как? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2007, 10:54 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
просто замечание. имхо, в подобных циклах Код: plaintext 1. лучше ставить Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2007, 17:38 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
aak__просто замечание. имхо, в подобных циклах Код: plaintext 1. лучше ставить Код: plaintext 1. 2. БОЛЬШОЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО! Сделал так Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Полёт нормальный. Теперь не жрёт 98% CPU Теперь всё как у взрослых - CPU отжирает постепенно, по мере возрастания нагрузки и потом отпускает до 0.0% ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2007, 18:23 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
да. есть такая фича в performance tuning )))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.04.2007, 18:38 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Zmeishe Полёт нормальный. Теперь не жрёт 98% CPU Теперь всё как у взрослых - CPU отжирает постепенно, по мере возрастания нагрузки и потом отпускает до 0.0% Ты писал, что у тебя Теперь система показывает, что мой процесс жрёт 0.3-0.7% CPU и только во время обращения к БД и отправки ответа клиенту - потом 0.0 %CPU. итак все нормально. А по поводу, расстановки sleep-ов - ты просто избегаешь ошибку, а не исправляешь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.04.2007, 09:44 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Я также писАл: авторЭто ещё более топорная работа т.к. start() потока занимает какое-то время и клиент получат данные паузами. Если есть DataSet - мастер и у него много DataSet`ов - деталей - каждая деталь открывается с паузами в 1 сек. Это оч. долго. В первом варианте с while(!stop) их вообще не было А со sleep`ом, я остался на первом варианте, когда не одна функция некоего класса зашита в run(), а весь объект со всей байдой. Скорость оч. комфортная и никаких пауз между запросами. Паузы возникали либо на thread->start(), thread->stop() и опять thread->start(). Либо на mutex.lock(), mutex.unlock(). Со sleep`ом ничего этого нет, есть только скорость. AkhА по поводу, расстановки sleep-ов - ты просто избегаешь ошибку, а не исправляешь. Может быть. После такой сильной разницы со sleep`ом и без, пока рано что-либо утверждать. Подождём недельку. Если ежесуточных падений больше не будет, будем считать, что ошибки нет. Я думаю while(!stop); 98% CPU в одной нити не давали продыху другим нитям, что-либо делать ещё на системном уровне, вот оно и падало между thread->start() и приходом данных в канал. Ни то ни другое от меня не зависят, они системные, а системе как раз и не было продыху- типа занята. Будем посмотреть недельку. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.04.2007, 10:00 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Zmeishe AkhА по поводу, расстановки sleep-ов - ты просто избегаешь ошибку, а не исправляешь. Может быть. После такой сильной разницы со sleep`ом и без, пока рано что-либо утверждать. Подождём недельку. Если ежесуточных падений больше не будет, будем считать, что ошибки нет. Я думаю while(!stop); 98% CPU в одной нити не давали продыху другим нитям, что-либо делать ещё на системном уровне, вот оно и падало между thread->start() и приходом данных в канал. Ни то ни другое от меня не зависят, они системные, а системе как раз и не было продыху- типа занята. Будем посмотреть недельку. Системе продых дается. Иначе у тебя все бы повисло на мертво. Я не призываю тебя не пользоваться sleep() - наоборот, это правельный подход. Но у тебя был хороший шанс отладится, а ты его упускаешь. Хочешь, копи глюки дальше. Когда напишешь большую программу, в которой будет несколько таких глюков, то ты потеряешь над ней контроль, а отладить ее будет на порядки сложнее, чем по одиночке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.04.2007, 10:19 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Zmeishewhile(!stop); этта, может у тебя кулер на проце уже старенький, да и просто перегревается проц, когда долго идет 100-процентная загрузка ? Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.04.2007, 10:38 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Akh Но у тебя был хороший шанс отладится Согласен. Но для того, чтобы отладиться, необходимо придумать методику такой отладки. Мне пока в голову ничего не приходит. Я на форум пришёл не для того чтобы мою проблему решали за меня, а для того чтобы подсказали методику поиска этой ошибки. Если бы косяк был в тексте программы - его рано или поздно через дебаггер увидеть можно. Собственно до этого я так и сделал - локализовав ошибку, заставил её проявляться постоянно, а не случайно, и на конкретные действия. А тут ошибка во время коннекта клиента, а в коннекте между стартом нити и готовностью принимать данные в сокете. У меня на эти действия ни строчки кода - это либо в библиотеке Qt, либо в системе, либо у меня чего-то отсутствует (напр. sleep()). А как дебаггер покажет чего отсутствует? На нет и суда нет. Можно, конечно, придумать способ измерения нагрузки на другие нити в то время, когда происходит очередной коннект, ну а дальше что? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.04.2007, 10:48 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Карабас Барабасда и просто перегревается проц, когда долго идет 100-процентная загрузка В серверной как в холодильнике - там кондиционер арктический тропик создаёт. 10 мин и уже про тулупчик заячий вспоминаешь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.04.2007, 10:51 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
ZmeisheА тут ошибка во время коннекта клиента, а в коннекте между стартом нити и готовностью принимать данные в сокете. После создания нового серверного сокета для клиента, он сразу готов к приему данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.04.2007, 10:58 |
|
||
|
Сокетный сервер (многопоточный)
|
|||
|---|---|---|---|
|
#18+
Akhсразу готов к приему данных. Он то готов, но событие о прибытии данных ещё не наступило для программы, а функция thread->start() уже отработала. Программа уже скомандовала старт нити и ждёт, когда же нить фактически стартует и ждёт прихода запроса от клиента. И тут ошибка - она В ГДЕ? Между чем и чем? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.04.2007, 11:10 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=34458245&tid=2029012]: |
0ms |
get settings: |
5ms |
get forum list: |
20ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
167ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
60ms |
get tp. blocked users: |
1ms |
| others: | 242ms |
| total: | 513ms |

| 0 / 0 |
