Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Дано: Linux Debian 8.5, прога на gcc-4.9, которая опрашивает периферию по протоколу UDP порт 1234. Периферия присылает на порт 1234 пакет авторизации, где указан код узла и IP-адрес периферии. согласно этим данным головной поток устанавливает соединение и считывает данные с периферии. Когда задач авторизации приходит много, головной поток не успевает их обработать и задачи "теряются". Если бы каждый узел периферии работал со своим портом UDP, то проблем нет - многопоточный обмен. Но здесь порт один и если я открою скажем два потока, то поток может запросто "схватить" чужой пакет и информация так же потеряется. Подскажите уважаемые профессионалы, как организовать обмен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 07:08 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
UDP пакеты могут теряться, это нормально. Для начала просто увеличь размер буфера сокета. Код: plaintext 1. 2. 3. 4. Если не поможет, то выноси подготовку ответа в отдельный поток. Т.е. один поток принимает UDP пакеты и ставит в очередь на обработку, второй извлекает из очереди, обрабатывает и отправляет ответ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 07:35 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dima T, Спасибо большое. буфера мне вполне хватает, проблема в том, что один сеанс обмена с периферией, это примерно 30 запрос-ответов, и в это время приходит задача авторизации от другого узла периферии, которая сейчас просто игнорируется до окончания сеанса обмена с текущим узлом. если я создам отдельный поток на обработку ответов, то тоже проблема, допустим один узел находится на 15 шаге запрос-ответов, второй на втором шаге запрос-ответов, а третий только что прислал задачу авторизации. Как разрулить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 07:43 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Асинхронно обрабатывать. Сделай структуру для хранения текущего состояния обмена в одним авторизующимся, там храни все что касается его, т.е. текущее состояние синхронизации. Назовем ее auth_t У каждого спрашивающего есть какой-то свой уникальный IP:порт, используй его как идентификатор. Все структуры собери в map Код: plaintext 1. Чтобы компараторы не писать можешь "IP:порт" преобразовать в int64_t Дальше алгоритм простой, в цикле: ждешь UDP пакет, по приходу пакета получаешь указатель на структуру данного отправителя Код: plaintext 1. по данным из пакета и структуры формируешь ответ, меняешь состояние авторизации в структуре и т.д. и т.п. Вобщем все что там у тебя по алгоритму обмена положено. В начало цикла. Так хоть 100500 параллельно обрабатывай. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 08:21 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dima T, Спасибо большое! Смысл поняла. Осталось придумать как опрос разбить на шаги. допустим опрашиваю в цикле часовые архивы. приходит ответ <IP:port:номер шага> и получается, что надо нырнуть в середину цикла опроса часовых архивов, если перед этим занималась чем-то другим. А перед входом в цикл там куча значений вычисляется (маркер архива, общее число показаний и тп, индекс цикла) Если это все поместить в структуру, описывающую узел периферии, то это монстр какой-то получится. Никогда не разбивала программу на изолированные шаги, чтобы можно было в любой момент выйти на некоторое время и зайти в программу снова не потеряв предыдущих вычислений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 08:56 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Mari.PОсталось придумать как опрос разбить на шаги. допустим опрашиваю в цикле часовые архивы. приходит ответ <IP:port:номер шага> и получается, что надо нырнуть в середину цикла опроса часовых архивов, если перед этим занималась чем-то другим. Запоминать состояние в структуре auth_t, т.е. при отправке запроса запоминаем там: отправлен запрос архива, а по приходу ответа смотрим там что запрашивали. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 09:24 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dima T, Да, по-ходу это очередь получается. Когда-то давно (в 1991 году) мы такое в MS-DOS реализовывали. Там не было возможности создавать потоки и наш шеф написал библиотеку, имитирующую многопоточность. Те была прога обработки очереди, на вход которой подавались структуры заданий (например один шаг цикла). А каждая клиентская прога должна была разбить свое выполнение на задания и подсовывать их в очередь. Таким образом вроде бы все выполнялось параллельно. Вот никогда бы не подумала, что мне это вспомнить придется ))) Спасибо большое! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 09:48 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Mari.PА перед входом в цикл там куча значений вычисляется (маркер архива, общее число показаний и тп, индекс цикла) Если это все поместить в структуру, описывающую узел периферии, то это монстр какой-то получится. Никогда не разбивала программу на изолированные шаги, чтобы можно было в любой момент выйти на некоторое время и зайти в программу снова не потеряв предыдущих вычислений. По хорошему надо именно так и делать. Но если у тебя синхронный алгоритм, то его придется вывернуть наизнанку. Можно по другому, оставить твой алгоритм как есть. Если одновременно обменов не много, то можно сделать через отдельные потоки и очереди. Вместо очереди можешь UDP порт на 127.0.0.1 использовать. Делаешь хранилище очередей Код: plaintext 1. При запуске потока обмена он открывает UDP сокет на 127.0.0.1:* и регистрирует его в queue Поток приема UDP принимает пакет со внешнего порта, находит в queue локальный порт куда переслать и пересылает. Поток обработки принимает с локального порта, а отправляет во внешний. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 09:54 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dima T, Как сказать немного, узлов 300, задачу авторизации каждый узел генерит 1 раз в 5 мин... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 10:07 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Mari.PDima T, Как сказать немного, узлов 300, задачу авторизации каждый узел генерит 1 раз в 5 мин... Не обязательно 300 потоков постоянно держать. Хотя можно и держать, комп выдержит, но некрасиво это. Одновременно, как понял, максимум обмен с 2-3 узлами идет, поэтому лучше так: при необходимости обмена с конкретным узлом запускается отдельный поток, обменивается и завершается. Тогда лишних потоков висеть не будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 10:23 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dima TПоток обработки принимает с локального порта, а отправляет во внешний. Если так будешь делать, то отправку во внешний не забудь обернуть в блокировку мутексом, чтобы разные потоки одновременно не слали. Принимать одним потоком и слать другим можно, а вот слать несколькими - это под вопросом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 10:35 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dima T, Так не буду делать, буду "наизнанку выворачивать". Как-то некорректно все-таки пришедший готовый пакет еще куда-то отправлять.... Хотя да, процедуру обмена придется полностью переписывать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 11:39 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Mari.PКак-то некорректно все-таки пришедший готовый пакет еще куда-то отправлять.... Конечно некорректно. Зачем громоздить такие сложности, когда достаточно реализовать паттерн producer-consumer, а в consumer встроить конечный автомат с состоянием? Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 13:26 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovMari.PКак-то некорректно все-таки пришедший готовый пакет еще куда-то отправлять.... Конечно некорректно. Зачем громоздить такие сложности, когда достаточно реализовать паттерн producer-consumer, а в consumer встроить конечный автомат с состоянием? паттерн producer-consumer - а что это? не подскажете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 14:24 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Шаблон проектирования Producer-Consumer . ИМХО лишнее это, он для высоконагруженных систем, для 300 обменов раз в 5 минут одного потока хватит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 14:46 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dima TИМХО лишнее это, он для высоконагруженных систем, для 300 обменов раз в 5 минут одного потока хватит. Раз у аффтара теряются пакеты, значит не хватает. Помимо всего прочего, такой рефакторинг повысит модульность и как следствие - сопровождаемость кода. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 15:13 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovРаз у аффтара теряются пакеты, значит не хватает. Не теряются, она их сама не обрабатывает, т.к. алгоритм синхронный 20175832 Mari.Pпроблема в том, что один сеанс обмена с периферией, это примерно 30 запрос-ответов, и в это время приходит задача авторизации от другого узла периферии, которая сейчас просто игнорируется до окончания сеанса обмена с текущим узлом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 15:17 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovDima TИМХО лишнее это, он для высоконагруженных систем, для 300 обменов раз в 5 минут одного потока хватит. Раз у аффтара теряются пакеты, значит не хватает. Помимо всего прочего, такой рефакторинг повысит модульность и как следствие - сопровождаемость кода. пакеты не теряются, я их сама игнорировала, пока не закончу обмен. сейчас сделала временные костыли - храню в массиве структур пришедшие во время сеанса обмена задачи авторизации от других узлов и по окончании обмена обрабатываю их. Один сеанс длится где-то около 5 сек, так что вроде успеваю. Но вообще говоря переделывать надо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 15:19 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Mari.PЕсли это все поместить в структуру, описывающую узел периферии, то это монстр какой-то получится не обязательно монстр, структура может быть просто развесистой PS а в качестве примера можно посмотреть исходники nginx ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 15:23 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
ИзопропилPS а в качестве примера можно посмотреть исходники nginx Ничего себе там исходников-то..... https://trac.nginx.org/nginx/browser?_ga=1.32480254.1376089487.1487152273#nginx/src/core Сейчас с синхронным алгоритмом наблюдается ситуация - единственный поток ждет пакет, в это время сыплются пакеты от других узлов и нужный "теряется", приходится перезапрашивать. У меня один вопрос - допустим один поток ждет пакет UDP на порту 1234. Код: plaintext 1. Другой поток может посылать пакеты по UDP в тот же порт 1234? Это не приведет к тому, что первый поток ничего не дождется? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2017, 14:01 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Mari.PУ меня один вопрос - допустим один поток ждет пакет UDP на порту 1234. Код: plaintext 1. Другой поток может посылать пакеты по UDP в тот же порт 1234? Это не приведет к тому, что первый поток ничего не дождется? Что пришлют то и получит. Слать можно откуда угодно, открывай в другом потоке новый сокет и шли с него на 127.0.0.1:1234. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2017, 14:18 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dima TMari.PУ меня один вопрос - допустим один поток ждет пакет UDP на порту 1234. Код: plaintext 1. Другой поток может посылать пакеты по UDP в тот же порт 1234? Это не приведет к тому, что первый поток ничего не дождется? Что пришлют то и получит. Слать можно откуда угодно, открывай в другом потоке новый сокет и шли с него на 127.0.0.1:1234. хочу сделать два основных потока - один только ждет на порту 1234 и сплавляет временным потокам пакеты, открывая новые потоки если узел свежий - второй только отправляет на порт 1234 пакеты, которые ему будут поставлять временные потоки в виде очереди. - куча временных потоков, открываемых на время сессии с конкретным узлом. Вопрос - первый и второй потоки не будут друг другу мешать? Короче можно делать отправку и получение "одновременно" или надо семафорить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2017, 14:29 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Mari.PВопрос - первый и второй потоки не будут друг другу мешать? Не будут. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2017, 14:33 |
|
||
|
помогите с логикой, туплю
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakov, Спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.02.2017, 14:49 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=39398266&tid=2018273]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
170ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
54ms |
get tp. blocked users: |
1ms |
| others: | 279ms |
| total: | 546ms |

| 0 / 0 |
