crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Выбор и реализация типа многопоточности, пул потоков, поток на соединение или один поток
mezmay
  опции профиля:
сообщение 27.11.2012, 23:53
Сообщение #1


Активный участник
***

Группа: Участник
Сообщений: 272
Регистрация: 13.7.2009
Из: Ростов-на-Дону
Пользователь №: 904

Спасибо сказали: 16 раз(а)




Репутация:   1  


Для саморазвития решил написать чат с базой данных, многопоточностью и голосовой связью. Клиенты будут подключаться к серверу и все сообщения посылать через него. Как реализовать многопоточность в данном случае? Хорошо понимаю 2 варианта:

1. Один дополнительный поток. Он все время запущен, принимает коннекты и передает/принимает данные от всех клиентов, пишет в базу.
2. Один поток на каждое соединение. Запущен пока есть коннект, обменивается данными с одним клиентом ну и пишет в общую базу.
3. Хотелось бы услышать советы, ведь оба предложенных варианта нехорошие - первый плох тем, что будет перегружен один поток, а второй плох тем, что количество потоков зависит от количества подключений и может быть неоптимальным. Изучал документацию по пулу потоков в Qt, но так и не понял как его прикрутить к данной задаче, ведь надо сделать чтобы рабочий объект существовал в потоке в течении, как минимум, одного коннекта. Или может сразу создать несколько потоков и клиентов распихивать по ним?...

Сообщение отредактировал mezmay - 27.11.2012, 23:57
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 28.11.2012, 6:29
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


можно попробовать так:

1) поток с GUI (основной)

2) поток сервера - слушает соединения, подключает

3)а) поток обслуживания клиентов - работает с массивом клиентов. Перебирает по очереди подключения, опрашивает, исполняет, отсылает
3)б) либо каждого клиента обрабатывать отдельным потоком (но это более морочно, и вряд ли понадобится)


и не забывать про синхронизацию, конечно

Сообщение отредактировал Алексей1153 - 28.11.2012, 6:30
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mezmay
  опции профиля:
сообщение 29.11.2012, 13:30
Сообщение #3


Активный участник
***

Группа: Участник
Сообщений: 272
Регистрация: 13.7.2009
Из: Ростов-на-Дону
Пользователь №: 904

Спасибо сказали: 16 раз(а)




Репутация:   1  


Я все-таки хочу использовать количество рабочих потоков, равное QThread::idealThreadCount(),
и начал делать так: один поток принимает коннекты и запускает по мере необходимости рабочие потоки, в которые передает принятые сокеты. Таким образом получается, что у меня запущено, например, 8 рабочих потоков, и каждый обрабатывает по 4 клиента. Вот например от клиента А пришло сообщение для клиента В, но клиент А обрабатывается в одном потоке, а клиент В в другом, как в этом случае передать к В принятые от А данные?

Сообщение отредактировал mezmay - 29.11.2012, 13:43
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 29.11.2012, 14:22
Сообщение #4


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


усложнения с настройкой количества потоков - сомнительная выгода. Не советую :) Лучше тогда по одному потоку на клиента. И не париться.

Цитата(mezmay @ 29.11.2012, 16:30) *
Вот например от клиента А пришло сообщение для клиента В, но клиент А обрабатывается в одном потоке, а клиент В в другом, как в этом случае передать к В принятые от А данные?

не понял вопроса. Если это соединённые клиенты с разных концов сокета, то один передаёт в сокет, другой принимает из сокета.
Или что имеется в виду ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mezmay
  опции профиля:
сообщение 29.11.2012, 14:32
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 272
Регистрация: 13.7.2009
Из: Ростов-на-Дону
Пользователь №: 904

Спасибо сказали: 16 раз(а)




Репутация:   1  


Ну допустим у нас по одному потоку на клиента - проблемы те же. Пользователь А шлет сообщение пользователю В. Оно приходит на сервер в поток threadA и в нем считывается. Пользователь В обрабатывается в потоке threadB (ну то есть соответствующий этому пользователю сокет QTcpSocket). Итак, сообщение от пользователя А принято в потоке threadA, а отправлено должно быть пользователю В. Как это сделать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 29.11.2012, 14:36
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


в твоём классе-потоке сервера должен быть список подключенных им сокетов клиентов. Сокеты ты каким-то образом маркируешь - вот по этой метке и найдёшь, кому передать данные
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mezmay
  опции профиля:
сообщение 29.11.2012, 14:48
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 272
Регистрация: 13.7.2009
Из: Ростов-на-Дону
Пользователь №: 904

Спасибо сказали: 16 раз(а)




Репутация:   1  


Да, сокеты хранить и найти нужный не проблема. Но как синхронизировать? Нельзя же писать в один сокет socketB из двух потоков одновременно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 29.11.2012, 18:10
Сообщение #8


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


по-моему, тебе лучше разделить потоки на приём и отправку. тогда у тебя будут уникальные точки входа. ну а более простую синхронизацию - стандартными средствами. наверняка в Qt поддерживаются мьютексы и прочие средства синхронизации потоков.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 30.11.2012, 11:11
Сообщение #9


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(mezmay @ 29.11.2012, 17:48) *
Нельзя же писать в один сокет socketB из двух потоков одновременно

это в доках сказано ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
mezmay
  опции профиля:
сообщение 30.11.2012, 15:26
Сообщение #10


Активный участник
***

Группа: Участник
Сообщений: 272
Регистрация: 13.7.2009
Из: Ростов-на-Дону
Пользователь №: 904

Спасибо сказали: 16 раз(а)




Репутация:   1  


Из документации QAbstractSocket:
Цитата
Note: It is not possible to initialize two abstract sockets with the same native socket descriptor.

Ну а использовать один нельзя, т.к. он не thread-safe
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 22.11.2024, 22:11