Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.54/26: Рейтинг темы: голосов - 26, средняя оценка - 4.54
28 / 29 / 5
Регистрация: 17.10.2009
Сообщений: 739
1

Многопоточный чат с использованием пула потоков

23.03.2014, 19:10. Показов 4674. Ответов 55
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
есть вопрос как реализовать можно чат с использованием пулов потоков.Без пула все понятно на каждого клиента создается поток и потоки висят и делают свои дела,в пуле я читал создается n-ое количество потоков и они обрабатывают свои задачи,тоесть если у меня 4 потока в пуле то только 4 пользователя смогут работать и все,а остальные будут в очереди или я не правильно что то понимаю

Добавлено через 43 минуты
неужели никто не использовал пул потоков?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.03.2014, 19:10
Ответы с готовыми решениями:

Вызов конструктора и деструктора с использованием пула
У меня есть некоторая область памяти (указатель на её начало и размер в байтах), часть которой...

Помощь с использованием потоков
Добрый вечер, вот пишу программу, которая создает 2 потока, первый считает в файле кол-во символов...

Обработка матриц с использованием файлов и потоков
Задание такое: Создать класс matrica с заранее неизвестным количеством элементов. Предусмотреть...

Максимальный элемент матрицы с использованием потоков
#include "stdafx.h" #include <Windows.h> #include <iostream> #include <conio.h> using...

55
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
25.03.2014, 14:00 21
Author24 — интернет-сервис помощи студентам
будут вопросы - можно в личку писать
1
70 / 47 / 5
Регистрация: 10.01.2017
Сообщений: 1,849
05.11.2022, 21:38 22
Цитата Сообщение от Jupiter Посмотреть сообщение
так в чем вопрос? появился клиент - достали из пула поток и отдали его клиенту, если свободного потока нету, поставили клиента в очередь
Интересует момент "если свободного потока нету, поставили клиента в очередь" - как он по Вашему реализуется ?

Предположим созданы 10 потоков, усыплены, потом предположим подключились 10 клиентов и просто условно 5 минут занимают каждый по своему соединению, то есть свободных потоков нет.

И как это реализуется ? Вам же все равно нужно вызвать фикцию прослушивать "accept", а для нее создать сокет, но ведь все 10 сокетов уже созданы и заняты, а значит 11 сокет создавать нельзя.

Что именно Вы советовали поместить в очередь ?
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
05.11.2022, 21:47 23

Не по теме:

Optimus11, у человека последняя активность в 2017. Он вам не ответит.



Тем не менее я ответить могу, потому что это известный паттерн и не он его придумал.
Цитата Сообщение от Optimus11 Посмотреть сообщение
ведь все 10 сокетов уже созданы и заняты, а значит 11 сокет создавать нельзя.
Чего эт нельзя? Сокет - это ведь не поток. Потоков, допустим, 10, а сокетов может быть сколько нужно. Только часть из них будут в очереди после подключения.
1
70 / 47 / 5
Регистрация: 10.01.2017
Сообщений: 1,849
05.11.2022, 22:50 24
Цитата Сообщение от DrOffset Посмотреть сообщение

Не по теме:

Optimus11, у человека последняя активность в 2017. Он вам не ответит.



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

Чего эт нельзя? Сокет - это ведь не поток. Потоков, допустим, 10, а сокетов может быть сколько нужно. Только часть из них будут в очереди после подключения.
А если постоянно выделять память под сокеты, а потом эту память освобождать - фрагментации памяти рано или поздно не случится ?
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
05.11.2022, 23:06 25
Цитата Сообщение от Optimus11 Посмотреть сообщение
А если постоянно выделять память под сокеты
Зачем выделять память под сокеты? Кроме места в очереди, память которой может быть в пуле, никакой памяти для этого не нужно.
0
70 / 47 / 5
Регистрация: 10.01.2017
Сообщений: 1,849
06.11.2022, 12:46 26
Цитата Сообщение от DrOffset Посмотреть сообщение
Зачем выделять память под сокеты? Кроме места в очереди, память которой может быть в пуле, никакой памяти для этого не нужно.
После закрытия сокета, он уже не валидный и использовать его для accept-прослушивателя уже не получается, а значит нужно создать новый сокет, а значит нужно выделить под него память и поместить указатель на него в очередь.

Или я просто не понимаю тогда, как по другому.
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
06.11.2022, 13:06 27
Цитата Сообщение от Optimus11 Посмотреть сообщение
После закрытия сокета
В какой момент предполагается его закрывать?
Если это новый клиент, то под него будет новый сокет. Естественно он будет открыт.
Если этой старый клиент в очереди, то сокет под него не закрыт. Клиент просто ждет, когда его обслуживание на сервере начнется. Это активное ожидание.
Итого не понятно в чем вы видите проблему.
0
70 / 47 / 5
Регистрация: 10.01.2017
Сообщений: 1,849
06.11.2022, 13:15 28
Цитата Сообщение от DrOffset Посмотреть сообщение
В какой момент предполагается его закрывать?
Когда или Сервер отдал все что нужно или когда Клиент закрыл соединение.

Цитата Сообщение от DrOffset Посмотреть сообщение
Если это новый клиент, то под него будет новый сокет. Естественно он будет открыт.
Если этой старый клиент в очереди, то сокет под него не закрыт. Клиент просто ждет, когда его обслуживание на сервере начнется. Это активное ожидание.
Итого не понятно в чем вы видите проблему.
Я имел ввиду:

-Я создаю-выделяю память под сокет и ставлю его на прослушивание.
-Приходит Входящие "сообщение" от Клиента - я читаю и отвечаю - после чего закрываю сокет и освобождаю ранее выделенную под него память.
-Создаю-выделяю новый сокет и ставлю его на прослушивание ...
-Приходит Входящие "сообщение"
-итд итд

Вот эти непрерывные выделения памяти и освобождение под непрерывно создающиеся и уничтожающиеся сокеты - к фрагментации памяти в итоге не приведут ?
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
06.11.2022, 13:32 29
Цитата Сообщение от Optimus11 Посмотреть сообщение
непрерывные выделения памяти и освобождение под непрерывно создающиеся и уничтожающиеся сокеты - к фрагментации памяти в итоге не приведут ?
Если память будет в пуле, то нет. Размеры объектов всегда одинаковые. Я же написал об этом выше.

Цитата Сообщение от Optimus11 Посмотреть сообщение
Я создаю-выделяю память под сокет и ставлю его на прослушивание.
Сокет - это объект ядра. В общем случае ничего кроме этого числа под него на стороне пользователя выделять не надо. На стороне пользователя это просто число\структура. Возможно вы имеется в виду объект-обертку над сокетом?

Цитата Сообщение от Optimus11 Посмотреть сообщение
Приходит Входящие "сообщение" от Клиента - я читаю и отвечаю - после чего закрываю сокет и освобождаю ранее выделенную под него память.
В целом схема разрывать соединение после каждого законченного цикла обмена применяется, но совсем не обязательна. В условном "чате" так она скорее вредна. Можно ведь сохранять соединение активным и только переводить клиента в режим ожидания, если от него нет сообщений. Отключить его можно, например, по прошествии определенного времени, как длительно неактивного.

С другой стороны в условном "чате" какая-то особенная многопоточность тоже не нужна. Как вариант можно сделать пулы клиентов на N штук в каждом, каждый пул - это отдельный поток. Пихать одного клиента чата в отдельный поток, даже временно, это расточительно. Нет там такой нагрузки.
0
70 / 47 / 5
Регистрация: 10.01.2017
Сообщений: 1,849
06.11.2022, 13:40 30
Цитата Сообщение от DrOffset Посмотреть сообщение
Если память будет в пуле, то нет. Размеры объектов всегда одинаковые. Я же написал об этом выше.
Да, но это касается чистых сокетов видимо.


Цитата Сообщение от DrOffset Посмотреть сообщение
Сокет - это объект ядра. В общем случае ничего кроме этого числа под него на стороне пользователя выделять не надо. На стороне пользователя это просто число\структура. Возможно вы имеется в виду объект-обертку над сокетом?
Да я имел ввиду: boost::asio::ip::tcp::socket - который еще и требует указать параметры при создании - поэтому его в пул - в вектор или список поместить и не удается, а удается создать только через new и сохранить указатель:

C++
1
boost::asio::ip::tcp::socket* my_socket_p = new boost::asio::ip::tcp::socket(io_context);

Может быть ранее закрытий сокет можно переиспользовать для нового соединения ? Можно ли его как то "сбросить" в первоначальное состояние, как будто бы его только что создали ?
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
06.11.2022, 13:52 31
Цитата Сообщение от Optimus11 Посмотреть сообщение
поэтому его в пул - в вектор или список поместить и не удается, а удается создать только через new и сохранить указатель:
Не вижу причин почему его нельзя поместить в пул.
Конечно можно. Но не в вектор, естественно, а в правильно написанный пул памяти.
В том же бусте есть аллокаторы на пулах.

Цитата Сообщение от Optimus11 Посмотреть сообщение
Да, но это касается чистых сокетов видимо.
Нет, это и всяких оберток тоже касается.

Добавлено через 2 минуты
Цитата Сообщение от Optimus11 Посмотреть сообщение
Можно ли его как то "сбросить" в первоначальное состояние, как будто бы его только что создали ?
Безотносительно этой задачи, в целом, всегда лучше работать с новым объектом, чем переиспользовать старый. Однако новый объект может быть в старой памяти, но это уже уровнем ниже и на описываемой логике на сказывается.
0
70 / 47 / 5
Регистрация: 10.01.2017
Сообщений: 1,849
06.11.2022, 13:55 32
Цитата Сообщение от DrOffset Посмотреть сообщение
Не вижу причин почему его нельзя поместить в пул.
Конечно можно. Но не в вектор, естественно, а в правильно написанный пул памяти.
В том же бусте есть аллокаторы на пулах.
А чем принципиально правильно написанный пул памяти - будет отличатся от вектора ?

Почему в вектор поместить объект бустовского сокета нельзя, а в специально написанный можно ?

C++
1
2
3
4
5
boost::asio::ip::tcp::socket* my_socket_p = new boost::asio::ip::tcp::socket(io_context);  //Так можно
 
std::vector<boost::asio::ip::tcp::socket>my_vec;
my_vec.resize(1);
my_vec[0] = boost::asio::ip::tcp::socket(io_context);        //Так нельзя, так как буст сокет не поддерживает конструктор копирования
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
06.11.2022, 14:00 33
Цитата Сообщение от Optimus11 Посмотреть сообщение
А чем принципиально правильно написанный пул памяти - будет отличатся от вектора ?
Тем, что вектор распоряжается объектами, а пул - памятью.
0
70 / 47 / 5
Регистрация: 10.01.2017
Сообщений: 1,849
06.11.2022, 14:06 34
Цитата Сообщение от DrOffset Посмотреть сообщение
Тем, что вектор распоряжается объектами, а пул - памятью.
А Вы можете подсказать, что мне нужно почитать, чтобы понять, что же это за пул-памяти в который можно будет "создавать" бустовский-сокет ? На данный момент, что то совершенно не соображу о чем речь.
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
06.11.2022, 14:23 35
Цитата Сообщение от Optimus11 Посмотреть сообщение
что мне нужно почитать
http://dmitrysoshnikov.com/com... allocator/
https://www.boost.org/doc/libs... index.html
https://en.wikipedia.org/wiki/Free_list

Еще есть вот такая вариация на тему:
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <boost/intrusive/slist.hpp>
#include <boost/noncopyable.hpp>
#include <cassert>
 
namespace internal
{
 
namespace bi = ::boost::intrusive;
 
template <typename Tp>
class pool_allocator
    : boost::noncopyable
{
    struct storage_type
    {
        unsigned char dummy[sizeof(Tp)];
    };
    struct node : storage_type
    {
        bi::slist_member_hook<> hook;
    };
    typedef bi::slist<
         node
       , bi::member_hook<node, bi::slist_member_hook<>, &node::hook>
       , bi::constant_time_size<false>
    > FreeList;
 
    struct disposer
    {
        void operator()(node * p) { delete p; }
    };
 
public:
    ~pool_allocator()
    {
        m_freeList.clear_and_dispose(disposer());
    }
 
    void * allocate(std::size_t x)
    {
        assert(x == sizeof(Tp));
        if(!m_freeList.empty())
        {
            void * p = void_cast(&m_freeList.front());
            m_freeList.pop_front();
            return p;
        }
        return void_cast(new node);
    }
 
    void deallocate(void * p)
    {
        assert(p != NULL);
        node & n = *static_cast<node *>(storage_cast(p));
        m_freeList.push_front(n);
    }
 
private:
    static void * void_cast(storage_type * p)
    {
        return p;
    }
    static storage_type * storage_cast(void * p)
    {
        return static_cast<storage_type *>(p);
    }
 
private:
    FreeList m_freeList;
};
 
} // namespace internal
1
70 / 47 / 5
Регистрация: 10.01.2017
Сообщений: 1,849
06.11.2022, 15:24 36
Спасибо, однако таки не понятно, каким образом "запихнуть" бустовский сокет в этот пул памяти.

Если бустовский сокет можно создать только таким образом:

C++
1
boost::asio::ip::tcp::socket* my_socket_p = new boost::asio::ip::tcp::socket(io_context);
0
2832 / 2337 / 707
Регистрация: 29.06.2020
Сообщений: 8,658
06.11.2022, 15:35 37
Цитата Сообщение от Optimus11 Посмотреть сообщение
Если бустовский сокет можно создать только таким образом:
Почему ?
C++
1
2
3
4
5
6
7
8
ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), 80);
ip::tcp::socket sock(service);
sock.open(ip::tcp::v4());
sock.connect(ep);
sock.write_some(buffer("GET /index.html\r\n"));
char buff[1024]; sock.read_some(buffer(buff,1024));
sock.shutdown(ip::tcp::socket::shutdown_receive);
sock.close();
0
70 / 47 / 5
Регистрация: 10.01.2017
Сообщений: 1,849
06.11.2022, 15:42 38
Цитата Сообщение от SmallEvil Посмотреть сообщение
Почему ?
Ну так создайте таким образом бустовский сокет, чтобы он создался в выделенном пуле памяти, а не абы где.

C++
1
ip::tcp::socket sock(service);
0
2832 / 2337 / 707
Регистрация: 29.06.2020
Сообщений: 8,658
06.11.2022, 16:01 39
Цитата Сообщение от Optimus11 Посмотреть сообщение
Ну так создайте таким образом бустовский сокет, чтобы он создался в выделенном пуле памяти, а не абы где.
Я такие объекты еще на паскале в обычный массив ложил.
У вас проблема не в этом.
0
70 / 47 / 5
Регистрация: 10.01.2017
Сообщений: 1,849
06.11.2022, 16:08 40
Цитата Сообщение от SmallEvil Посмотреть сообщение
Я такие объекты еще на паскале в обычный массив ложил.
У вас проблема не в этом.
Укажите пожалуйста на проблему.
0
06.11.2022, 16:08
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.11.2022, 16:08
Помогаю со студенческими работами здесь

Поиск в бинарном файле с использованием файловых потоков
Подскажите как реализовать поиск объекта в бинарном файле.(телефонный справочник, поиск по названию...

Сервер с использованием пула потоков для параллельной обработки запросов клиентов
Разработать сервер с использованием пула потоков для параллельной обработки запросов клиентов. К...

Синхронизация пула потоков
Всем привет! Задаю я, наверное, такой вопрос не первый и уж явно не последний. Тема такая: using...

Ожидание завершения пула потоков
Нужно чтоб результат этого кода возвращался по завершению выполнения всех потоков в пуле ...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru