Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++, SFML] Strumień cin i blokowanie pętli głównej programu

Ostatnio zmodyfikowano 2014-07-15 11:39
Autor Wiadomość
Rughailon
Temat założony przez niniejszego użytkownika
[C++, SFML] Strumień cin i blokowanie pętli głównej programu
» 2014-07-13 12:18:20
Witam.
Chciałbym mieć możliwość pisania w konsoli bez przerywania obiegu pętli. Zdecydowałem się skorzystać z wątków, które oferuje SFML, ale to nadal nie działa.

Kod:
C/C++
std::string write_command() {
    std::string text;
    std::cin >> text;
   
    return text;
}

int main( int argc, char * argv[] ) {
   
    //...
   
    sf::Thread threat_write( & write_command );
   
    while( run ) {
        if( selector.wait( sf::seconds( 2 ) ) ) {
            if( selector.isReady( manager.listener ) ) {
                //...
            }
           
           
            for( int i = 0; i < v_user.size(); ++i ) {
                if( selector.isReady( * v_user[ i ].socket ) ) {
                    manager.receive_package( v_user[ i ].socket );
                    if( !check_phrase( manager.get_last_type_packet(), "PACKET_NOTHING_ERROR" ) )
                         std::cout << "Message received: \"" << manager.get_last_type_packet() << "\"" << std::endl;
                    //...
                }
            }
        }
        threat_write.launch();
    }
P-113731
Monika90
» 2014-07-13 15:44:06
ale to nadal nie działa
czyli co?

BTW, chyba lepiej będzie używać std::thread zamiast sf::Thread. Każdy zna standardowe wątki, o SFML-owych trzeba czytać w dokumentacji, więc używając standardowych zwiększasz szanse na to, że ktoś Ci pomoże.
P-113740
Witold
» 2014-07-14 08:20:59
C/C++
#include <SFML/System/Thread.hpp>
#include <iostream>
#include <string>

bool thread_running = false;
std::string text;

void thread_func()
{
    std::cin >> text;
    thread_running = false;
}

int main()
{
    sf::Thread thread( & thread_func );
   
    while( true )
    {
        if( !thread_running )
        {
            if( !text.empty() )
            {
                std::cout << "Entered :" << text << std::endl;
                if( text == "exit" )
                     break;
               
            }
            thread_running = true;
            thread.launch();
        }
    }
    return 0;
}
P-113761
Rughailon
Temat założony przez niniejszego użytkownika
» 2014-07-14 18:25:15
@Monika90
Obieg pętli nadal zostanie przerwany, dopóki nie wprowadzę tekstu.
Co do std::thread. Nie widzę potrzeby, gdyż jego odpowiednik przy innych rzeczach działa dobrze.

@Witold
Działa! Dzięki wielkie. :)
P-113795
Monika90
» 2014-07-14 18:36:48
@Witold
Działa! Dzięki wielkie. :)
o tak działa... zachowanie tego programu jest niezdefiniowane
P-113796
Rughailon
Temat założony przez niniejszego użytkownika
» 2014-07-14 22:42:04
@Monika90
Czemu? Wszystko działa, jak powinno.
P-113804
Monika90
» 2014-07-15 00:15:08
Czemu?
Ponieważ jeden wątek modyfikuje zmienną thread_running, a drugi odczytuje jej wartość w tym samym czasie. W takiej sytuacji zachowanie jest niezdefiniowane. Jeżeli zastąpisz bool przez std::atomic<bool> to powinno być OK. Najlepiej jednak jak nie wiesz jak działają wątki, to ich nie używaj.

Wszystko działa, jak powinno.
Miałeś szczęście.

Obieg pętli nadal zostanie przerwany, dopóki nie wprowadzę tekstu.
To dlatego, że wywołanie threat_write.launch() wstrzymuje wątek wywołujący do czasu zakończenia się wątku reprezentowanego przez obiekt threat_write. Twórcom SFML nie chciało się tego napisać w dokumentacji.
P-113808
Rughailon
Temat założony przez niniejszego użytkownika
» 2014-07-15 11:39:19
W takim razie dzięki. Już rozumiem. :)
P-113815
« 1 »
  Strona 1 z 1