Мониторинг сокета UDP в glib (мм) расходует процессорное время - PullRequest
3 голосов
/ 15 июня 2010

У меня есть приложение GTKmm для Windows (с MinGW), которое получает пакеты UDP (без отправки).Сокет является родным winsock, и я использую glibmm IOChannel для подключения его к основному циклу приложения.Сокет читается с помощью recvfrom.

Моя проблема заключается в том, что эта установка потребляет 25% процессорного времени на рабочей станции 3GHz.Может кто-нибудь сказать мне, почему?

Приложение в этом случае бездействует, и если я удаляю код UDP, загрузка ЦП падает почти до нуля.Поскольку приложение должно выполнять некоторые задачи, интенсивно использующие процессор, я мог бы изобразить лучшие способы потратить эти 25%

Вот некоторые выдержки из кода: (извините за printf;))


/* bind */
void UDPInterface::bindToPort(unsigned short port)
{
    struct sockaddr_in target;
    WSADATA wsaData;

    target.sin_family = AF_INET;
    target.sin_port = htons(port);
    target.sin_addr.s_addr = 0;

    if ( WSAStartup ( 0x0202, &wsaData ) )
    {
        printf("WSAStartup failed!\n");
        exit(0); // :)
        WSACleanup();
    }

    sock = socket( AF_INET, SOCK_DGRAM, 0 );
    if (sock == INVALID_SOCKET)
    {
        printf("invalid socket!\n");
        exit(0);
    }

    if (bind(sock,(struct sockaddr*) &target, sizeof(struct sockaddr_in) ) == SOCKET_ERROR)
    {
        printf("failed to bind to port!\n");
        exit(0);
    }

    printf("[UDPInterface::bindToPort] listening on port %i\n", port);
}

/* read */
bool UDPInterface::UDPEvent(Glib::IOCondition io_condition)
{
    recvfrom(sock, (char*)buf, BUF_SIZE*4, 0, NULL, NULL);
    /* process packet... */
}

/* glibmm connect */
Glib::RefPtr channel = Glib::IOChannel::create_from_win32_socket(udp.sock);
Glib::signal_io().connect( sigc::mem_fun(udp, &UDPInterface::UDPEvent), channel, Glib::IO_IN );

Я прочитал здесь в каком-то другом вопросе, а также в glib docs (g_io_channel_win32_new_socket ()), что сокет переведен в неблокирующий режим, и это «побочный эффект от реализации и неизбежности».Объясняет ли это эффект ЦП, мне не ясно?

Кажется ли, что я использую glib для доступа к сокету или вызова recvfrom () напрямую, не имеет большого значения, так как ЦП использовался раньшелюбой пакет прибывает, и обработчик чтения вызывается.Также glibmm docs заявляет, что нормально вызывать recvfrom (), даже если сокет опрашивается (Glib :: IOChannel :: create_from_win32_socket ())

Я пытался скомпилировать программу с -pg и создал функцию для каждойОтчет об использовании процессора с помощью gprof.Это было бесполезно, потому что время тратится не на мою программу, а на некоторые внешние glib / glibmm dll.

...