Código
#include <iostream> int main(int argc, char *argv[]) { sleep(1); std::cout << "Hello world" << std::endl; return 0; }
El cual mostraba el mensaje "Hello world" antes del sleep, y digo mostraba porque mientras escribía el hilo, he ido a compilar el código y me ha funcionado como debería (con gcc 4.6.4)
Con gcc 4.8.1 también funciona a la perfección:
Código
#include <iostream> #include <thread> #include <chrono> int main(int argc, char *argv[]) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::cout << "Hello world" << std::endl; return 0; }
Tal vez sea que en aquel entonces tenía una versión de gcc más antigua que tenía este problema, o quizás que por aquel entonces compilaba con entornos como Geany, y ahora compilo por linea de comandos por SSH, que aunque lo que realmente importe sea el compilador y no el IDE, no sé, quizás algo tenía por ahí que no iba bien.
El caso es que siempre he programado bajo Windows y no le di demasiada importancia a lo anterior, pero ahora estoy programando un cliente y un servidor con sockets, y la aplicación del servidor la programo en un VPS con Ubuntu 12.04, por lo que este bug (o así al menos lo considero yo), esta vez tengo que quitármelo de en medio.
Yendo ya al grano, estoy haciendo un servidor con threads, y mientras que un hilo gestiona los paquetes recibido por los clientes, tengo un otro hilo de prueba que simplemente printea un punto con pausas de 30ms
Código
Client::Client(MYSQL *m) : mysql(m), connected(true), acc_id(0) { mutex.lock(); playingM.lock(); thread = std::thread(&Client::loop, this); thread.detach(); coordT = std::thread(&Client::updateCoords, this); coordT.detach(); cout << "Client constructed." << endl; } void Client::updateCoords() { playingM.lock(); while(true) { cout << "."; std::this_thread::sleep_for(std::chrono::milliseconds(30)); } } void Client::loop() { mutex.lock(); while(connected) { sf::Packet packet; if(receive(packet) == sf::Socket::Done) { unsigned char pid; packet >> pid; if(pid!=0x00) cout << "Packet ID: " << (unsigned short)pid << " | from " << getRemoteAddress().toString() << " | (account.id: " << acc_id << ")." << endl; switch(pid) { case 0x00: { ... } break; case 0x01: { ... } break; case 0x02: { ... } break; case 0x03: { ... } break; case 0x04: { ... } break; case 0x05: { ... } break; case 0x06: { ... playingM().unlock(); ... } break; default: break; } } else { cout << "A client has disconnected (account.id: " << acc_id << ")." << endl; delete this; } } }
Simplifico Client::loop() y aclaro que en cada case hay couts que son printeados inmediatamente en cuanto llega determinado paquete, mientras que el cout << "."; en Client::updateCoords() no printea nada hasta que lo hace cualquier otro cout en Client::loop(), es como si todos esos puntos se almacenasen en un buffer y de repente se printean todos juntos, cuando al tratarse de 2 hilos independientes, debería de printear por su propia cuenta.
Esto me parece más problema de la librería SFML que de Linux, aunque en Windows no tenga este problema, pero no descarto que la librería funcione de otra forma en Linux y por ello sea culpa de los threads de SFML. En un principio pensaba que era simplemente problema de Linux, ya que lo asocié a lo que expliqué al principio que me pasó hace tiempo, pero al ver que ésto ya no me ocurre, pienso que será cosa de SFML, pero no tengo nada claro.
EDITO: No hacer mucho caso a esto último, ya que los threads que uso no son de SFML sino de C++11, lapsus mental :X queda totalmente descartado SFML como causa del problema
Alguien puede aportar algún dato? Gracias y saludos
PD: Habré tardado como una hora en hacer este hilo, el título incluso lo considero incorrecto debido a mi cambio de opinión al ver que el problema del sleep ya no me ocurre, dudaba si postear en el foro de Linux o en el de C++, pero me decanto más por este, en fin, no sé, este proyecto me está estresando, así que publico el hilo ya y fin. XD