Как Вы реализовали бы основной цикл событий?

Нашел мое решение благодаря Ошибка с .htaccess и mod_rewrite Для Apache 2.4 и во всех * .conf файлах (например, httpd-vhosts.conf, http.conf, httpd-autoindex.conf .. и т. д.) используйте

Require all granted

вместо

Order allow,deny
Allow from all

Директивы Order и Allow устарели в Apache 2.4.

55
задан fengshaun 18 March 2009 в 14:37
поделиться

4 ответа

Я раньше задавался вопросом много о том же!

основной цикл GUI А похож на это в псевдокоде:

void App::exec() {
    for(;;) {
        vector<Waitable> waitables;
        waitables.push_back(m_networkSocket);
        waitables.push_back(m_xConnection);
        waitables.push_back(m_globalTimer);
        Waitable* whatHappened = System::waitOnAll(waitables);
        switch(whatHappened) {
            case &m_networkSocket: readAndDispatchNetworkEvent(); break;
            case &m_xConnection: readAndDispatchGuiEvent(); break;
            case &m_globalTimer: readAndDispatchTimerEvent(); break;
        }
    }
}

, Что такое "Waitable"? Ну, это - системный иждивенец. На UNIX это назвало "дескриптор файла", и "waitOnAll":: выберите системный вызов. Так называемое vector<Waitable> ::fd_set на UNIX, и "whatHappened" на самом деле запрашивается через FD_ISSET. Фактические waitable-дескрипторы получены различными способами, например m_xConnection может быть взят от:: XConnectionNumber (). X11 также обеспечивает высокий уровень, портативный API для этого-:: XNextEvent () - но если бы необходимо было использовать это, Вы не были бы в состоянии ожидать на нескольких источниках события одновременно .

, Как блокирование работает? "waitOnAll" является syscall, который говорит ОС помещать Ваш процесс в "список сна". Это означает, что Вам не дают процессорного времени, пока событие не имеет место на одном из waitables. Это, тогда, означает, что Ваш процесс неактивен, используя 0% ЦП. Когда событие будет иметь место, Ваш процесс будет кратко реагировать на него и затем возвращаться к состоянию ожидания. Приложения для GUI тратят почти весь их время, бездействуя.

, Что происходит со всеми циклами ЦП, в то время как Вы спите? Зависит. Иногда другой процесс будет иметь использование для них. В противном случае Ваша ОС будет занятый цикл ЦП, или помещать его во временный режим низкой мощности, и т.д.

, спросите для получения дальнейшей информации!

71
ответ дан 7 November 2019 в 17:15
поделиться

Обычно я делал бы это со своего рода семафор подсчета :

  1. Семафор запускается в нуле.
  2. Цикл событий ожидает на семафоре.
  3. Событие (события) входит, семафор увеличен.
  4. Обработчик событий разблокирует и постепенно уменьшает семафор и обрабатывает событие.
  5. , Когда все события обрабатываются, семафор является блоками нулевого и цикла событий снова.

, Если Вы не хотите добираться, который усложнил, Вы могли просто добавить сон () вызов в Вашем цикле с условием продолжения с тривиально маленьким временем сна. Это заставит Ваше сообщение, обрабатывающее поток уступать, это - процессорное время к другим потокам. ЦП больше не будет привязан в 100%, но это все еще довольно расточительно.

11
ответ дан Eric Petroelje 7 November 2019 в 17:15
поделиться

Python:

можно посмотреть на реализацию Скрученный реактор , который является, вероятно, лучшей реализацией для цикла событий в Python. Реакторы в Скрученном являются реализациями интерфейса, и можно определить реактор типа для выполнения: выберите, epoll, kqueue (все на основе c API с помощью тех системных вызовов), существуют также реакторы на основе QT и инструментариев GTK.

А простая реализация должна была бы использовать выбор:

#echo server that accepts multiple client connections without forking threads

import select
import socket
import sys

host = ''
port = 50000
backlog = 5
size = 1024
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host,port))
server.listen(backlog)
input = [server,sys.stdin]
running = 1

#the eventloop running
while running:
    inputready,outputready,exceptready = select.select(input,[],[])

    for s in inputready:

        if s == server:
            # handle the server socket
            client, address = server.accept()
            input.append(client)

        elif s == sys.stdin:
            # handle standard input
            junk = sys.stdin.readline()
            running = 0

        else:
            # handle all other sockets
            data = s.recv(size)
            if data:
                s.send(data)
            else:
                s.close()
                input.remove(s)
server.close() 
21
ответ дан Vasil 7 November 2019 в 17:15
поделиться

Я пользовался бы простой, легкой библиотекой обмена сообщениями под названием ZeroMQ ( http://www.zeromq.org/ ). Это - библиотека с открытым исходным кодом (LGPL). Это - очень небольшая библиотека; на моем сервере целый проект компилирует приблизительно за 60 секунд.

ZeroMQ чрезвычайно упростит Ваш событийно-ориентированный код, И это - также наиболее эффективное решение с точки зрения производительности. При передаче между использованием потоков ZeroMQ намного быстрее (с точки зрения скорости), чем использование семафоров или локальных сокетов UNIX. ZeroMQ также быть 100%-м портативным решением, тогда как все другие решения привязали бы Ваш код к определенной операционной системе.

10
ответ дан 7 November 2019 в 17:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: