Приложение-клиент принимает данные с двух портов одного сервера. Скорость потока небольшая, около 2Кб/с, что сильно меньше пропускной способности сетевого подключения клиента. Процессор на клиенте современный ARMv7 или x86-64. Что лучше относительно экономии ресурсов клиента:
1. Запустить один поток и ждать через epoll. При доступности данных читать в неблокирующемся режима оба сокета по очереди (если доступны оба).
2. Запустить по потоку на сокет и читать в блокирующемся режиме.
Как рассчитать во втором варианте возможность потери данных. Как вообще рассчитать возможность потери пакета UDP, если данные забираются из буфера слишком поздно? Прав ли я, что если разницы особой нет, то запуская один поток, экономятся ресурсы ОС, так как нет лишнего переключения контекста?
Здравствуйте, mbait, Вы писали:
M> M>1. Запустить один поток и ждать через epoll. При доступности данных читать в неблокирующемся режима оба сокета по очереди (если доступны оба). M>2. Запустить по потоку на сокет и читать в блокирующемся режиме. M>
Если у вас один сокет, лучше использовать poll() или select(). epoll — хорошая штука, но ее преимущества раскрываются, если сокетов много.
M>Как рассчитать во втором варианте возможность потери данных. Как вообще рассчитать возможность потери пакета UDP, если данные забираются из буфера слишком поздно? Прав ли я, что если разницы особой нет, то запуская один поток, экономятся ресурсы ОС, так как нет лишнего переключения контекста?
Еще и мозговые ресурсы программиста экономятся. В многопоточной программе возникает много интересных и весьма нетривиальных вопросов, которые в однопоточной программе просто не возникают.
Как вы, например, собираетесь останавливать этот поток, который висит в блокирующемся чтении из сокета?
Здравствуйте, Pzz, Вы писали:
Pzz>Еще и мозговые ресурсы программиста экономятся. В многопоточной программе возникает много интересных и весьма нетривиальных вопросов, которые в однопоточной программе просто не возникают.
Pzz>Как вы, например, собираетесь останавливать этот поток, который висит в блокирующемся чтении из сокета?
Здравствуйте, mbait, Вы писали:
Pzz>>Как вы, например, собираетесь останавливать этот поток, который висит в блокирующемся чтении из сокета?
M>Хорошая мысль, не подумал об этом.
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, mbait, Вы писали:
Pzz>>>Как вы, например, собираетесь останавливать этот поток, который висит в блокирующемся чтении из сокета?
M>>Хорошая мысль, не подумал об этом.
Pzz>Ну и правильно. Думать вредно.
А вот сейчас подумал, и решил, что shutdown(2) заставит блокирующие вызовы вернуть -1.
Здравствуйте, mbait, Вы писали:
M> M>1. Запустить один поток и ждать через epoll. При доступности данных читать в неблокирующемся режима оба сокета по очереди (если доступны оба). M>
Лучше первое, но его сложнее сделать. Можно взять готовую либу вроде boost::asio или libevent. Можно использовать вместо epoll — select. M>Как рассчитать во втором варианте возможность потери данных. Как вообще рассчитать возможность потери пакета UDP, если данные забираются из буфера слишком поздно? Прав ли я, что если разницы особой нет, то запуская один поток, экономятся ресурсы ОС, так как нет лишнего переключения контекста?
У тебя слишком мало потоков, можно пренебречь переключением контекста.
Здравствуйте, Kernan, Вы писали:
K>Лучше первое, но его сложнее сделать. Можно взять готовую либу вроде boost::asio или libevent. Можно использовать вместо epoll — select.
Есть какие-то скрытые трудности? Никогда не работал с epoll до этого, работал с libevent, но пример из "Example of suggested usages" epoll(2) вопросов не вызывает.
Здравствуйте, mbait, Вы писали:
M>Здравствуйте, Kernan, Вы писали:
K>>Лучше первое, но его сложнее сделать. Можно взять готовую либу вроде boost::asio или libevent. Можно использовать вместо epoll — select.
M>Есть какие-то скрытые трудности? Никогда не работал с epoll до этого, работал с libevent, но пример из "Example of suggested usages" epoll(2) вопросов не вызывает.
Там не то, что сложности много, просто чуть больше кода и немного посложнее логика приложения. Если проблем не вызывает, то пиши смело.
Здравствуйте, SkyDance, Вы писали:
Pzz>>Как вы, например, собираетесь останавливать этот поток, который висит в блокирующемся чтении из сокета?
SD>Взять да закрыть сокет, да хоть из UI-треда.
А теперь представим себе, что мы закрываем сокет из какого-то одного потока, а какой-нибудь другой поток тем временем еще чего-нибудь открывает. В юниксе это чего-нибудь получит первый свободный файловый дескриптор. Т.е. тот, который только что освободился из-под сокета. Ну а в венде — как повезет. А поток, который работает с сокетом, он про это ничего не знает. Поэтому он и продолжит себе работать, как ни в чем не бывало. С совершенно посторонним для него файловым дескриптором. Вот уж он с ним наработает-то, ко всеобщему изумлению.
Pzz>А теперь представим себе, что мы закрываем сокет из какого-то одного потока, а какой-нибудь другой поток тем временем еще чего-нибудь открывает. В юниксе это чего-нибудь получит первый свободный файловый дескриптор. Т.е. тот, который только что освободился из-под сокета. Ну а в венде — как повезет. А поток, который работает с сокетом, он про это ничего не знает. Поэтому он и продолжит себе работать, как ни в чем не бывало. С совершенно посторонним для него файловым дескриптором. Вот уж он с ним наработает-то, ко всеобщему изумлению.
Напиши программу, которая воспроизводит это поведение, и удивись.
Здравствуйте, Pzz, Вы писали:
Pzz>А теперь представим себе, что мы закрываем сокет из какого-то одного потока, а какой-нибудь другой поток тем временем еще чего-нибудь открывает. В юниксе это чего-нибудь получит первый свободный файловый дескриптор. Т.е. тот, который только что освободился из-под сокета. Ну а в венде — как повезет. А поток, который работает с сокетом, он про это ничего не знает. Поэтому он и продолжит себе работать, как ни в чем не бывало. С совершенно посторонним для него файловым дескриптором. Вот уж он с ним наработает-то, ко всеобщему изумлению.
Здравствуйте, mbait, Вы писали:
M> M>1. Запустить один поток и ждать через epoll. При доступности данных читать в неблокирующемся режима оба сокета по очереди (если доступны оба). M>2. Запустить по потоку на сокет и читать в блокирующемся режиме. M>
второе. не надо плодить сложности на ровном месте.
M>Прав ли я, что если разницы особой нет, то запуская один поток, экономятся ресурсы ОС, так как нет лишнего переключения контекста?
экономия на спичках, а точнее даже так, вы пытаетесь решать проблему которой нет ( перформанс при трафике в 2кб/c ).