event driven - зло или несовсем? (и чуть-чуть QT or not QT?)
и, насколько я понимаю, к 4 версии все стало только хуже?
В одном Qt потоке может жить только один Qt сокет.О да... Если у вас даже не получается запустить в одном потоке несколько qt-сокетов - может стоит сметь профессию?
и, насколько я понимаю, к 4 версии все стало только хуже?Без понятия, я это чудо начал тискать с версии 4.0.1
О да... Если у вас даже не получается запустить в одном потоке несколько qt-сокетов - может стоит сметь профессию?Без понятия, не получается у коллеги. Кажется, Qt что-то спамит в debug окно. Это не отменяет других пунктов, которые, очевидно, poor designed.
не получается у коллегиА у тебя получается?
А у тебя получается?Я не пробовал. Но использовать Qt сокет синхронно - пробовал. Никому этого не пожелаю.
Я не пробовал.Так вот в чём проблема.
Но использовать Qt сокет синхронно - пробовал. Никому этого не пожелаю.Дык может нужно было запустить его Асинхронно, чтобы он не мешал работать другим?
void Server::initSocket
{
udpSocket = new QUdpSocket(this);
udpSocket->bind(QHostAddress::LocalHost, 7755);
connect(udpSocket, SIGNAL(readyRead
this, SLOT(readPendingDatagrams;
}
void Server::readPendingDatagrams
{
while (udpSocket->hasPendingDatagrams {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize;
QHostAddress sender;
quint16 senderPort;
udpSocket->readDatagram(datagram.data datagram.size
&sender, &senderPort);
processTheDatagram(datagram);
}
}
Красота, даже беркли-сокеты отдыхают.
Дык может нужно было запустить его Асинхронно, чтобы он не мешал работать другим?Зачем мне запускать его асинхронно, когда я адаптировал его для пакета, который работает с сокетами синхронно и никому не мешает? Не все программисты приверженцы пихания event driven подхода во все возможные дыры, чтобы программа заодно была менее читабельной.
который работает с сокетами синхронно и никому не мешаетогда объясни, как в одном треде делаешь синхронную запись/чтения без event-driven?
тогда объясни, как в одном треде делаешь синхронную запись/чтения без event-driven?Очень просто: протокол запрос-ответ. Асинхронность реализации этого протокола никому никуда не впилась. Qt вместо этого предлагает засунуть в рот ноги и всё равно прикрутить event driven. Это poor design of network library. Мне не известно других сетевых библиотек, которые не позволяют простые проблемы решать просто. Тоже самое касается и необходимости делать это всё в одном потоке, тогда как запись и чтение можно делать из разных потоков одновременно, повышая производительность системы.
Работать с сетью без событийной машины — зло.
Работать с сетью без событийной машины — зло.Протокол запрос-ответ не нуждается в эвентах.
И, кроме того, даже потоковые протоколы не нуждаются в эвентах на уровне сокета. Удобнее читать синхронно, производить анализ и преобразование потока байтов в поток объектов, и уже по факту появления новго объекта посылать сообщения.
Протокол запрос-ответ не нуждается в эвентах.
Это неправда.
ты будешь ждать при чтении после accept и просасывать?
И, кроме того, даже потоковые протоколы не нуждаются в эвентах на уровне сокета
Потоковые протоколы идут нахуй. Вернее, ты можешь обрабатывать все потоково, но работа с сетью должна производиться в одном потоке.
Опять же, мелкие ненагруженные приложения можно вообще писать в стиле каком угодно.
можно вообще писать в стиле каком угоднону ему же не нравится как раз то, что qt не позволяет "как угодно".
типа забили на ленивых — значит poor design. =)
Просто потому что если напишешь проект на Qt, то потом с сетевое поделие не сделаешь быстро консольным — придется тащить всё Qt.
Не надо универсальных библиотек.
Это неправда.Да, я буду ждать при чтении. Точно так же, как очередь эвентов будет ждать, пока не придёт эвент. Только в моём случае течение программы не будет прерываться на ожидание эвента с сохраненим промежуточного состояния объекта.
ты будешь ждать при чтении после accept и просасывать?
Потоковые протоколы идут нахуй. Вернее, ты можешь обрабатывать все потоково, но работа с сетью должна производиться в одном потоке.Работа с сетью никому ничего не должна. Я могу параллельно посылать файл и принимать сообщения. Если запихать эти два независимых действия в один поток, то логика программы сильно усложнится.
Опять же, мелкие ненагруженные приложения можно вообще писать в стиле каком угодно.
ну ему же не нравится как раз то, что qt не позволяет "как угодно".Лень тут не при чём. Я не понимаю, зачем для реализации простого действия требуется сделать десяток сложных.
типа забили на ленивых — значит poor design. =)
Очень просто: протокол запрос-ответ. Асинхронность реализации этого протокола никому никуда не впилась.Вот из-за таких синхронных cool design и происходят тормоза сетевых приложений. Тот же стим не исключение.
Даже если выделяется один тред на одно соединение обработка всех событий просто необходима: тайм-ауты, внештатные ситуации и т.д. Синхронное чтение/запись - это блокировка треда.
Но если уж совсем хочется - ну запускай тред QT и делайте что хотите - обычный поток. Никто не принуждает пользоваться qtnetwork.
Тоже самое касается и необходимости делать это всё в одном потоке, тогда как запись и чтение можно делать из разных потоков одновременно, повышая производительность системы.О да, в вашем случае это особенно актуально.
Просто потому что если напишешь проект на Qt, то потом с сетевое поделие не сделаешь быстро консольным — придется тащить всё Qt.Да ничего страшного нет в этом. QTNetwork весит 300Кб в полном фарше, один файл.
Приложение легко делается консольным.
Qt - это прежде всего QtCore - не завязано на графику. Графика - QtGui, по сути опциональная.
Вобще суть в другом. QtNetwork позволяет работать асинхронно с сокетами в одном потоке с графикой. И это очень хорошо - нет заморочек с тредами и вобще вероятности ошибки, необходимости синхронизироваться по доступу к памяти и т.д.
Использовать другую библиотеку так не получится, не потому, что QT такой плохой, а потому что всё завязано основной loop обработки событий графической подсистемы (X11, Windows). Графика всегда будет на событиях, ну а синхронные сокеты в графике - это конкретные зависания.
Но ничто не мешает запустить тред и работать с обычными сокетами.
Если ты работаешь только с Qt - это гарантия того, что твой код будет корректно работать на всех плафтормах. Qtnetwork - не исключение. И это очень здорово.
Вот из-за таких синхронных cool design и происходят тормоза сетевых приложений. Тот же стим не исключение.Не путай реализацию протокола и архитектуру программы. Для реализации неблокирующего GUI вовсе необязательно использовать асинхронный сокет, зачастую порождая больше непонятного кода, чем это на самом деле необходимо. И, представь себе, все таймауты и внештатные ситуации прекрасно обрабатываются и без эвентов прямо на месте, где стоит запрос. Но, как я уже отметил, привыкшие к Qt программисты везде пихают эвенты, стремясь наделать столько дыр в program flow, сколько их в ситичке для чая.
Даже если выделяется один тред на одно соединение обработка всех событий просто необходима: тайм-ауты, внештатные ситуации и т.д. Синхронное чтение/запись - это блокировка треда.
Но если уж совсем хочется - ну запускай тред QT и делайте что хотите - обычный поток. Никто не принуждает пользоваться qtnetwork.Я уж лучше запущу тред из буста. Но увы, Qt объектам нужен Qt тред. Кроме того, никто не хочет тянуть в программу десятки сторонних библиотек.
Тоже самое касается и необходимости делать это всё в одном потоке, тогда как запись и чтение можно делать из разных потоков одновременно, повышая производительность системы.Да, в нашем случае это актуально. У нас есть реализация нескольких протоколов.
--------------------------------------------------------------------------------
О да, в вашем случае это особенно актуально.
Вобще суть в другом. QtNetwork позволяет работать асинхронно с сокетами в одном потоке с графикой.Угу. То есть, если я буду принимать сжатый zip поток данных, то скорость отклика GUI будет обратно пропорциональна скорости передачи данных по сети.
Если ты работаешь только с Qt - это гарантия того, что твой код будет корректно работать на всех плафтормах. Qtnetwork - не исключение. И это очень здорово.Кстати, что на счёт остальных недостатков?
Угу. То есть, если я буду принимать сжатый zip поток данных, то скорость отклика GUI будет обратно пропорциональна скорости передачи данных по сети.Считывай и распаковывай zip-поток небольшими кусками и отдавай управление в loop - всё будет ok.
Вот как раз в синхронном варианте - это целая беда.
Пришло много данных - а деваться некуда, нельзя откладывать.
Считывай и распаковывай zip-поток небольшими кусками и отдавай управление в loop - всё будет ok.руками организовывать кооперативную многозадачность?
и нахрен это надо?
что мы с этого получаем, кроме удорожания разработки?
ps
имхо, асинхронные решения нужны только в тех случаях, когда одновременно задач необходимо выполнять больше, чем разумное число тредов
во всех остальных случаях - лучше отдельные треды с синхронными запросами, чем все эти event driven замуты.
Считывай и распаковывай zip-поток небольшими кусками и отдавай управление в loop - всё будет ok.Во-первых, это не поможет. Загруженная работой очередь сообщений для GUI в любом случае понизит отклик (responsibility).
Во-вторых, зачем мне вводить какие-то небольшие куски, которые надо хранить как промежуточное состояние объекта, если бы я мог вообще реализовать весь протокол в виде отдельного объекта с асинхронным доступом только в тех местах, в которых это надо.
Вот пример псевдокода, о чём я говорю. Здесь пример реализации логина по протоколу POP3 с использованием синхронного сокета. Сам объект, реализующий протокол, может быть асинхронным. Напиши псевдокод, который переводит эту модель с синхронного чтения и pop на event driven и push.
std::string response;
m_pstrm->receive_message(response);
if (!response_ok(response
throw pop3_error("connection failed");
m_pstrm->send_message("USER " + user);
m_pstrm->receive_message(response);
if (!response_ok(response
throw auth_error("bad username");
m_pstrm->send_message("PASS " + pass);
m_pstrm->receive_message(response);
if (!response_ok(response
throw auth_error("bad password");
Вобще суть в другом. QtNetwork позволяет работать асинхронно с сокетами в одном потоке с графикой. И это очень хорошоДа, тогда я пожалуй соглашусь что это круто. Написание гуи с возможностью делать сетевые вещи.
Скорее мысль которуя я хотел донести — без гуи не надо использовать Qt.
Считывай и распаковывай zip-поток небольшими кусками и отдавай управление в loop - всё будет ok.Не, ерунжу говоришь.
Вот как раз в синхронном варианте - это целая беда.
Надо всего лишь запустить тред распаковки и ему передавать все что пришло.
![:)](/images/graemlins/smile.gif)
Надо всего лишь запустить тред распаковки и ему передавать все что пришло.А ещё лучше, чтобы этот поток работал с одним объектом, который делает все эти действия последовательно без эвентов.
А ещё лучше, чтобы этот поток работал с одним объектом, который делает все эти действия последовательно без эвентов.заебали вы своими объектами.
нету никаких объектов. ООП на помойку.
Надо всего лишь запустить тред распаковки и ему передавать все что пришло.А вот не факт.
Если, конечно, пишется аналог Download Master-a или skype, то да, причём в новый тред запихивать все соединения, нет смысла запускать распаковку в разных тредах, это не спасёт.
А вот к примеру icq, jabber, банк-клиент, тот же steam... Тоже zip может быть или шифрование. Тогда лучше иметь одно соединение с сервером в одном процессе с графикой, это сильно упрощает конструкцию.
Особенно в случае запрос-ответ.
В QT есть хороший пример - QHttp. Отличный пример грамотной организации протокола - составил запрос и забыл. Тебе сообщат уже когда будет готов ответ. Да, машина состояний, но она вся целиком в этом классе, никакой головной боли и никаких блокировок.
Хороший пример организации протокола - составил запрос и забыл. Тебе сообщат уже когда будет готов ответ. Да, машина состояний, но она вся целиком в этом классе, никакой головной боли и никаких блокировок.дык, в синхронном модели - еще все проще, вызвал и забыл, как выполнится - так тебе управление и вернут.
руками организовывать кооперативную многозадачность?Удорожание - это когда появляются треды.
и нахрен это надо?
что мы с этого получаем, кроме удорожания разработки?
Тогда нужно между ними организовывать message-passing, а это намного сложнее.
Пример:
Тайм-аут по соединению, полученый в одном треде (event-driven) будет тут же обработан графикой.
В случае тредов - он будет обработан отдельным тредом, передан в основной, и уже потом основным.
дык, в синхронном модели - еще все проще, вызвал и забыл, как выполнится - так тебе управление и вернут.Если это работает в одном потоке с графикой - пользователь будет очень часто лихорадочно клацкать мышкой по крестику и материть разработчиков.
нету никаких объектов. ООП на помойку.с каких это пор тред перестал быть объектом?
Если это работает в одном потоке с графикой - пользователь будет очень часто лихорадочно клацкать мышкой по крестику и материть разработчиков.а зачем это делать в том же потоке?
а зачем это делать в том же потоке?Уже написал.
вот к примеру icq, jabber, банк-клиент, тот же steam... Тоже zip может быть или шифрование. Тогда лучше иметь одно соединение с сервером в одном процессе с графикой, это сильно упрощает конструкцию.Ты просто подтверждаешь мои слова: люди, привыкшие к Qt всё путают и делают сложнее, чем требуется. Ещё раз повторю: я хочу сделать свой протокол. Использовать при его реализации асинхронные сокеты невыгодно. При этом никто не мешает объекту этого протокола быть асинхронным и даже общаться с GUI через эвенты.
Особенно в случае запрос-ответ.
В QT есть хороший пример - QHttp. Отличный пример грамотной организации протокола - составил запрос и забыл. Тебе сообщат уже когда будет готов ответ. Да, машина состояний, но она вся целиком в этом классе, никакой головной боли и никаких блокировок.
Ты так и не преобразовал мой псевдокод логина в POP3 в такой же, но на event driven модели. Мне кажется, что если ты это сделаешь, то мои возражения станут более чем очевидными.
Пример:В случае event driven без потоков эвент таймаута будет положен в очередь для GUI и обработан в соотв. функции. В случае с потоком поток положит точно такой же эвент в точно такую же очередь GUI.
Тайм-аут по соединению, полученый в одном треде (event-driven) будет тут же обработан графикой.
В случае тредов - он будет обработан отдельным тредом, передан в основной, и уже потом основным.
Ты так и не преобразовал мой псевдокод логина в POP3 в такой же, но на event driven модели. Мне кажется, что если ты это сделаешь, то мои возражения станут более чем очевидными.Не заметил сообщение:
class QPop {
private:
enum State {
NONE,
CONNECTED,
LOGIN_OK_RECV,
PASS_OK_RECV,
} state;
void OnConnect {
state = CONNECTED;
SendMsg (...);
}
void OnMsgRecv (const QString&) {
if (state == NONE) {
// Анализ полученных данных, ошибки и т.д.
state = LOGIN_OK_RECV;
SendMsg (...);
}
if (state == LOGIN_OK_RECV) {
// Анализ полученных данных, ошибки и т.д.
state = PASS_OK_RECV;
emit Result ;
}
}
public:
QPop (const QString& server, const QString& login, const QString& pass) : state (NONE)
{// Устанавливается соединение }
signals:
void Result ;
};
QPop* qpop = new QPop ("pop.mail.ru", "login", "password");
connect (qpop, Result ...);
В чём плюс:
* Выглядит посложнее, чем ты привёл, но сделай протокол чуть хитрее и использование статусов себя оправдвает.
* Никаких тредов, а это уже очень большой плюс.
* Пишется и отлаживается один раз всё это хозяйство - потом только используешь. Состояния не перемешиваются с состояниями класса.
В случае event driven без потоков эвент таймаута будет положен в очередь для GUI и обработан в соотв. функции.Вот, проброс евентов через треды.
А потом люди удивляются - а чтож у меня всё валится и как это отлаживать.
Вот, проброс евентов через треды.event driven - чаще дохнет, т.к. в event driven очень сложно отслеживать и data flow, и control flow.
А потом люди удивляются - а чтож у меня всё валится и как это отлаживать.
соответственно, довольна частая ошибка, что данные уже грохнули или еще не создали, а обращение к ним уже идет.
В чём плюс:Зачем делать POP3 протокол хитрее? Он ровно такой, каким описан в RFC1939. Кроме того хочу заметить, что во-первых тебе следовало использовать State паттерн. Ещё раз подтвердили правило, что разработчики Qt видят во всём только эвенты. Во-вторых ты затрахаешься делать автомат, когда тебе придётся решать другие задачи протокола POP3, например, считывать письмо до последовательности \r\n.\r\n. То есть чем протокол "хитрее", как ты выразился, тем больше промежуточных состояний у тебя будет.
* Выглядит посложнее, чем ты привёл, но сделай протокол чуть хитрее и использование статусов себя оправдвает.
* Никаких тредов, а это уже очень большой плюс.
* Пишется и отлаживается один раз всё это хозяйство - потом только используешь. Состояния не перемешиваются с состояниями класса.
Никаких тредов быть не может, потому что один поток не потянет больше десятков клиентов и GUI. И это факт.
Моя реализация тоже пишется и отлаживается один раз. Кроме того, отлаживать её гораздо проще в силу отсутствия дыр в program flow.
кол-во ошибок это здоровски уменьшило, и сильно подняло неубиваемость системы.
Вот, проброс евентов через треды.Эвенты и нужны в первую очередь для того, чтобы пробрасывать их через потоки. По крайней мере люди не напишут таких анекдотов:
А потом люди удивляются - а чтож у меня всё валится и как это отлаживать.
- Папа, а правда твоя ОС многозадачная?
- Правда.
- А покажи?
- Сейчас, дискетка доформатируется.
class QPop {Этот код даже не содержит работы с ошибками. То есть, добавь туда ещё и уведомления вышестоящего класса об ошибках и он разрастётся ещё больше. У меня, как ты видишь, это просто средства языка: throw.
private:
enum State {
NONE,
Edit: и ещё все connect'ы между этим классом и вышестоящими или между этим классом и сокетом... В общем, полный финиш.
во-первых тебе следовало использовать State паттерн.
нашёл к чему прие..ся..
Зачем делать POP3 протокол хитрее? Он ровно такой, каким описан в RFC1939.Да я в курсе, ты только малую часть его реализовал.
Во-вторых ты затрахаешься делать автомат, когда тебе придётся решать другие задачи протокола POP3, например, считывать письмо до последовательности \r\n.\r\n.Блин, не смеши.
До сих пор не затрахался.
Никаких тредов быть не может, потому что один поток не потянет больше десятков клиентов и GUI. И это факт.
Такс. А выбирать ту же почту как собрался - последовательно в одном потоке?
Вот тебе плюс - выборка той же почты с разных серверов будет происходить быстрее (асинхронный коннект) и не потребуется десятка тредов.
Кстати есть ещё один минус синхронной реализации - проблема экстренной остановки потока из другого треда.
Этот код даже не содержит работы с ошибками. То есть, добавь туда ещё и уведомления вышестоящего класса об ошибках и он разрастётся ещё больше. У меня, как ты видишь, это просто средства языка: throw.
Легко. Выставляешь код ошибки, бросаешь emit Result (errcode); или просто emit, а errnode спрашиваешь у класса.
Edit: и ещё все connect'ы между этим классом и вышестоящими или между этим классом и сокетом... В общем, полный финиш.Он там один, а с сокетом - 1-2 коннекта.
В общем я предлагаю тему закрыть, для себя я уже испытал все варианты. Для серверов я выбираю мультиплексирование в нескольких процессах или тредах, для клиентов - просто мультиплексирование в одном потоке.
Я просто советую причину вот этого
поведение программы варьируется от полной работоспособности, до спама дебаг сообщений и access violation.не искать в QT, а искать в своей архитектуре. Более чем уверен, что при отсутствии тредов жалоб на QT у вас было бы поменьше.
event driven - чаще дохнет, т.к. в event driven очень сложно отслеживать и data flow, и control flow.В основе большинства протоколов лежит система конечных состояний. И не всегда она выглядит так 1->2->3->4->5. Даже исходя из этого control flow легче отслеживать при асинхронном варианте.
соответственно, довольна частая ошибка, что данные уже грохнули или еще не создали, а обращение к ним уже идет.
И не всегда она выглядит так 1->2->3->4->5. Даже исходя из этого control flow легче отслеживать при асинхронном варианте.приведи пример хоть одного такого протокола
ftp
да даже pop - ветвление начинается, когда решается вопрос о способе авторизации. Но это мелко.
xmppxmpp - хз, что это.
ftp
в ftp - все плоско, все упихивается в if-ы и for-ы
да даже pop - ветвление начинается, когда решается вопрос о способе авторизации. Но это мелко.сихронный if уже отменили?
ps
я думал, ты знаешь, что когда идет спор асинк <-> синк (state или plain то считается, что протокол "плохой"(плохо ложится на синхронный вариант когда его состояния - не ложатся на скобочную запись.
нашёл к чему прие..ся..Это серьёзное замечание, учитывая какого размера у тебя получится ряд if-else, который вообще надо было сделать switch-ем и в котором у тебя уже есть ошибка.
Зачем делать POP3 протокол хитрее? Он ровно такой, каким описан в RFC1939.Я реализовал его полностью. Класс размером 265 строк реализации и 80 строк заголовка. Боюсь даже предположить, какого размера он получится при event driven подходе. А если мы ещё и сделаем его не на основе конкретного сокета, а на основе абстрактного текстового потока, что в общем-то правильно, то твой код распухнет, как женатый поп.
--------------------------------------------------------------------------------
Да я в курсе, ты только малую часть его реализовал.
Во-вторых ты затрахаешься делать автомат, когда тебе придётся решать другие задачи протокола POP3, например, считывать письмо до последовательности \r\n.\r\n.Ну что сказать, если ты просто не привык делать вещи так, чтобы их было удобно писать и отлаживать, то это просто подтверждает мои слова: Qt программисты очень ограничены и любое ООП решение сводят к ещё одному сигналу-слоту. Хотя мне было бы очень интересно посмотреть на полную реализацию POP3 на event driven, пусть даже без парсинга писем по RFC2822. Особенно интересным был бы момент, в котором кроме енума состояний пришлось бы создать буфер для временного хранения байтов тела письма.
--------------------------------------------------------------------------------
Блин, не смеши.
До сих пор не затрахался.
Вот тебе плюс - выборка той же почты с разных серверов будет происходить быстрее (асинхронный коннект) и не потребуется десятка тредов.С чего это ты взял, что выборка почты у тебя будет быстрее? У меня будет тред пул достаточного размера, чтобы во-первых, полностью загрузить канал; и во-вторых, порвать твою реализацию на Core Duo/Quadro.
Кстати есть ещё один минус синхронной реализации - проблема экстренной остановки потока из другого треда.Эта проблема есть только у объектов Qt. Нормальная реализация синхронных запросов может быть прервана из любого потока.
Этот код даже не содержит работы с ошибками. То есть, добавь туда ещё и уведомления вышестоящего класса об ошибках и он разрастётся ещё больше. У меня, как ты видишь, это просто средства языка: throw.
--------------------------------------------------------------------------------
Легко. Выставляешь код ошибки, бросаешь emit Result (errcode); или просто emit, а errnode спрашиваешь у класса.
Ага, то есть твой код ещё больше распухает. Кстати, сигнал ошибки тебе придётся запихать как в класс протокола, так и в класс транспорта для этого протокола.
Я просто советую причину вот этого
В ответ на:
--------------------------------------------------------------------------------
поведение программы варьируется от полной работоспособности, до спама дебаг сообщений и access violation.
--------------------------------------------------------------------------------
не искать в QT, а искать в своей архитектуре. Более чем уверен, что при отсутствии тредов жалоб на QT у вас было бы поменьше.
Я просто советую тебе не советовать никому ничего по поводу ООП архитектуры, если ты не признаёшь GoF или не способен сразу же разглядеть, к каким проблемам приведёт enum вместо state pattern в случае с протоколом POP3. А при отсутствии тредов клиенты начнут жаловаться на отсутствие responsibility в нашем GUI.
xmppПредставь себе, я реализовал этот протокол синхронно. И вообще я не понимаю, почему синхронная реализация мешает писать протоколы с состояниями. Кроме того, изначальный спор был о том, что Qt заставляет вещи, которые просто делаются без состояний, делать с состояниями. Что является минусом и poor design.
Даже исходя из этого control flow легче отслеживать при асинхронном варианте.Это вообще фраза, которая говорит о незнании теории. Чтобы спорить, что лучше: batch vs event, надо хотя бы знать определения и плюсы-минусы обоих подходов.
In computer programming, event-driven programming or event-based programming is a programming paradigm in which the flow of the program is determined by sensor outputs or user actions (mouse clicks, key presses) or messages from other programs or threads.
Из какой части этого определения ты сделал вывод о том, что control flow легче отслеживать в event driven?
А при отсутствии тредов клиенты начнут жаловаться на отсутствие responsibility в нашем GUI.В вашем - может быть, на наши однопотоковые GUI никто никогда не жаловался.
Qt программисты очень ограничены [..]Уважаемый, идите ка вы ищете баги в своём коде с таким отношением.
советую тебе не советовать никому ничего [..]
Эта проблема есть только у объектов Qt [..]
Вы всё правильно делаете - не на кого валить - валите на QT.
В вашем - может быть, на наши однопотоковые GUI никто никогда не жаловался.Просто в силу того, что они не выполняют никаких сложных действий.
Уважаемый, идите ка вы ищете баги в своём коде с таким отношением.
Вы всё правильно делаете - не на кого валить - валите на QT.
Уважаемый, идите ка вы вообще с таким отношением. Написал псевдокод в 2.5 раза больше по строкам, с ошибкой в логике, с ошибкой в проектировании, да ещё и продолжаешь утверждать что-то там про event driven, даже не зная определения того, что это такое. Слив защитан.
Просто в силу того, что они не выполняют никаких сложный действий.Это уже превращается в идиотизм.
Это уже превращается в идиотизм.Нет, в идиотизм превращается всё, что сказано до этого.
Во-первых, ты сказал, что отслеживать program flow проще в event driven подходе.
Во-вторых, ты написал псевдокод в два раза длинее и с логическими ошибками. Надеюсь, что ты понял, что был не прав. Но почему-то ты продолжил мяться и писать какую-то незначимую ерунду про наличие или отсутствие потоков в программе.
В-третьих, все твои аргументы были поностью покрыты: твоя программа тяжелее дебажится; не имеет ничего такого, что было бы сложнее делать при batch или mixed подходе; работает медленнее; содержит потенциальные проблемы, связанные с data flow; и содержит потенциальные проблемы, связанные с временем отклика GUI части.
Для интересующихся, если наш знаток Ash не найдёт правильных аргументов, то через некоторое время я сам напишу, когда event driven лучше.
Что ты там выдумываешь, какой линейкой измеряешь псевдокод (вобще бред) меня уже волнует мало. Я уже понял - доказать что-то тебе нереально и делать этого не собираюсь.
Если кто-то хочет подискутировать на эту тему - велкам, лучше в приват или в аську, но только при наличии адекватного поведения.
То что ты пишешь - это есть недопонимание концепций построения и реализаций протоколов вобще и сетевого взаимодействия в частности. В чём у тебя причина - я не знаю. Результат на лицо - гневные выпады в отношении Qt (и в мой адрес, но это пофиг хотя эта либа тут и близко не причём.Аргументы в студию. Все мои наезды более-менее обоснованы и очевидны по сообщениям в этой ветке. И как я вижу, кроме каких-то абстрактных ответов, крыть тебе не чем. Предлагаю в качестве аргументации реализацию протокола POP3 вплоть до полной загрузки байтов тела сообщения. Для простоты предлагаю взять только команды TOP, LIST, UIDL, PASS, USER, RETR.
Что ты там выдумываешь, какой линейкой измеряешь псевдокод (вобще бред) меня уже волнует мало. Я уже понял - доказать что-то тебе нереально и делать этого не собираюсь.Доказать мне что-то можно только аргументами, которые не являются противоречивыми. Ты же не споришь, что твоя фраза про control flow была неправильной. И вообще всё время уходишь от темы. Сначала у меня, оказывается, баги в программе. Да с чего ты это вообще взял? Перечисление недостатков Qt вовсе не означает, что у меня что-то не работает. Это лишь означает, что я использую Qt правильно, чтобы избежать этих проблем, и что это не удобно. Потом оказывается, что я что-то не умею делать. Как ты связал это и перечисление очевидных недостатков Qt я вообще слабо понимаю. Ближе к теме: Qt неудобно во многих случаях, а программисты на Qt решают все вопросы очередным слотом-сигналом, хотя в этой ветке уже показано, во что превращается такой подход. До сих пор не согласен - приводи агрументы, пиши код, а не беспочвенные домыслы.
поведение программы варьируется от полной работоспособности, до спама дебаг сообщений и access violation.
Сначала у меня, оказывается, баги в программе. Да с чего ты это вообще взял?
![:D](/images/graemlins/laugh.gif)
Перечисление недостатков Qt вовсе не означает, что у меня что-то не работает. Это лишь означает, что я использую Qt правильно [...]
Все мои наезды более-менее обоснованы и очевидныЯ хренею от самонадеянности.
Всё, ты Бог, пиши свои программы как хочешь, мне пофигу.
Я хренею от самонадеянности.Аргументов нет. Код для оценки ты писать не хочешь. Слив засчитан.
Всё, ты Бог, пиши свои программы как хочешь, мне пофигу.
Код для оценки ты писать не хочешь.Денег дашь?
Денег дашь?Зачем деньги? Очевидно, ты не можешь признать свою неправоту. Я предлагаю перевести теоретический спор в практическую плоскость. Я тоже напишу код, и готов его запостить первым. Тем более, мне не жалко 60-80 минут своего времени, чтобы поставить на место такого выскочку.
> происходить быстрее (асинхронный коннект) и не потребуется
> десятка тредов.
Тебе сюда.
---
...Я работаю антинаучным аферистом...
Оставить комментарий
kokoc88
Всё, наболело, не могу больше отмалчиваться про Qt.С одной стороны это, конечно, кроссплатформенный тулкит для написания софта на Си++: там есть и GUI, и сокеты, и подсчёт криптографического хэша, и строки аж с поддержкой трансляции байтов в различных кодовых страницах, и потоки.
Теперь поговорим о недостатках.
1. Мне кажется, что если начать работать в рамках этого тулкита, то выйти за них уже очень сложно. Либо всё на Qt, либо ничего. Это само по себе poor design.
2. Разработчики на Qt имеют какую-то маниакальную приверженность к event driven programming. Даже для двух объектов, которые агрегированы и работают в паре в одном потоке, пишется event driven управление. Причём соединения сигналов и слотов происходят обычно в разных файлах так, что приходится сделать full text search по проекту несколько раз, прежде чем поймёшь, как это всё работает. Вместо любого архитектурного решения разработчиками, привыкшими к Qt, сразу же предлагается соединить два класса через слот-сигнал.
3. При работе с Qt надо пользоваться потоками из Qt, что является poor design. Если этого не делать, то поведение Qt классов варьируется от спама дебаг сообщений до access violation.
4. Некоторые Qt объекты, которые созданы в одном потоке, нельзя удалять в другом. Деструктор вполне может вызвать terminate через qt_assert. Такой дизайн библиотеки для разработки софта можно было придумать только с сильного перепоя.
5. Qt Socket - это вообще отдельная песня. Я даже не знаю, что можно написать про такое гавно. В одном Qt потоке может жить только один Qt сокет. Если не следовать этому правилу, то поведение программы варьируется от полной работоспособности, до спама дебаг сообщений и access violation. Из сокета можно либо читать, либо туда писать. Только из одного потока. Вызов функций сокета в разных потоках приводит к... ну вы уже догадались, к чему.
Edit: В разных потоках можно использовать один сокет. Остальные проблемы остаются.