Problem With select()

Started by
3 comments, last by joomoo 18 years ago
I have a problem with select() under linux. When i run my code, who uses select() with a timeout {0, 0} select does not work. It crashes in a big timeout-loop. Here's the output from strace:
select(4, NULL, NULL, [3], {0, 0})      = 0 (Timeout)
select(4, [3], NULL, NULL, {0, 0})      = 0 (Timeout)
select(4, NULL, NULL, [3], {0, 0})      = 0 (Timeout)
select(4, [3], NULL, NULL, {0, 0})      = 0 (Timeout)
select(4, NULL, NULL, [3], {0, 0})      = 0 (Timeout)
select(4, [3], NULL, NULL, {0, 0})      = 0 (Timeout)
select(4, NULL, NULL, [3], {0, 0})      = 0 (Timeout)
select(4, [3], NULL, NULL, {0, 0})      = 0 (Timeout)
select(4, NULL, NULL, [3], {0, 0})      = 0 (Timeout)
select(4, [3], NULL, NULL, {0, 0})      = 0 (Timeout)
select(4, NULL, NULL, [3], {0, 0})      = 0 (Timeout)
select(4, [3], NULL, NULL, {0, 0})      = 0 (Timeout)
select(4, NULL, NULL, [3], {0, 0})      = 0 (Timeout)
select(4, [3], NULL, NULL, {0, 0})      = 0 (Timeout)
... many many many times
And this although there's something to send and recv. If i put in a timeout like one second it works but it's very slow and not what i want. I have to say, that this code worked fine on windows but not under linux. Anyone knows why there's a problem under linux with a {0, 0} timeout?
Advertisement
First, you only pass the file descriptor 3 to the read set and the exception set, so you won't ever be told if the socket is writable.

Second, how are you sure that there is something readable on file descriptor 3? If the call to select() returns 0, I would assume that there is actually nothing to read.

If it "works but is slow" when you put in a timeout, then the slowness is likely from somewhere else -- select() will return immediately if there is actually something to do.
enum Bool { True, False, FileNotFound };
Quote:Original post by hplus0603
First, you only pass the file descriptor 3 to the read set and the exception set, so you won't ever be told if the socket is writable.

The writable and the exception sets, are two different sets, so it must work (and it does work at the beginning before it gets stuck).

Quote:Second, how are you sure that there is something readable on file descriptor 3? If the call to select() returns 0, I would assume that there is actually nothing to read.

Im sure because i have a programm that sends and recvs, like PING-PONG, you know? And under windows that worked fine.

Quote:If it "works but is slow" when you put in a timeout, then the slowness is likely from somewhere else -- select() will return immediately if there is actually something to do.

Yes, i know, but i haven't any other sleep in my code, and the fact, that it's slow isn't the important fact. the important fact is that it does only work with a timeout.
Quote:Original post by joomoo
The writable and the exception sets, are two different sets, so it must work (and it does work at the beginning before it gets stuck).


What I'm saying is that, in your strace() output, the third argument to select() (the writable FD set) never gets set to anything other than NULL. That may be a clue to the problem.

If you break into the application using GDB when it's in the "stuck" mode, and trace through the code line by line, looking at the various variables of your code, does that tell you what's going wrong?
enum Bool { True, False, FileNotFound };
Okay you're right. I've tested again and i saw, that it gets everytime stuck when checking for read (first parameter). And this on both sides although it was programmed to changes it status when something arrived.

i don't know if that could help, but here's something of the source:

#include <iostream>#include "net.hpp"int main() {    for (;;) {        std::cout << "\nNeue Verbindung:\n0 - Server\n1 - Client\nDeine Eingabe: ";        bool sending;        std::cin >> sending;        net::Main Main(net::Signatur::Chat());        if (!sending) {            net::Listen Listen(&Main);            std::cout << "Warte auf Client";            while (Listen.Status() == net::Beschaeftigt) {                std::cout << "." << std::flush;                sleep(1);            }            if (Listen.Status() == net::Fehlgeschlagen) {                std::cout << "Fehlgeschlagen!\n";            }        }        else {            net::Connect Connect(&Main, "127.0.0.1");            std::cout << "Verbinde";            while (Connect.Status() == net::Beschaeftigt) {                std::cout << "." << std::flush;                sleep(1);            }            if (Connect.Status() == net::Fehlgeschlagen) {                std::cout << "Fehlgeschlagen!\n";            }        }        boost::shared_ptr<net::SRG> pSRG;        char RMich[5];        if (sending) {            pSRG.reset(new net::Send(&Main, "PING", sizeof("PING")));        }        else {            pSRG.reset(new net::Recv(&Main, RMich, sizeof(RMich)));        }        while (pSRG->Status() != net::Fehlgeschlagen) {            if (pSRG->Status() == net::Fertig) {                std::cout << "pSRG->Status() == net::Fertig" << std::endl;                sending = !sending;                std::cout << "Sending: " << sending << std::endl;                if (sending) {                    std::cout << RMich << std::flush;                    pSRG.reset(new net::Send(&Main, "PING", sizeof("PING")));                }                else {                    pSRG.reset(new net::Recv(&Main, RMich, sizeof(RMich)));                }            }            else if (pSRG->Status() == net::Fehlgeschlagen) {                std::cout << errno << strerror(errno) << std::endl;            }        }    }    return EXIT_SUCCESS;}


The classes are in the net.hpp which uses select() to check for messages. And this worked fine under windows. :(

mfg.

This topic is closed to new replies.

Advertisement