У меня есть приложение 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.