Si j'ai deux instances de Glib :: IOChannel, elles sont bloquées jusqu'à ce que les deux soient écrites. Quelle est la bonne façon de faire cela?

StackOverflow https://stackoverflow.com/questions/1043588

  •  20-08-2019
  •  | 
  •  

Question

J'ai modifié l'exemple trouvé ici pour utiliser deux canaux io. Aucun des rappels ne semble avoir été appelé avant que j'aie écrit sur les deux canaux. Après cela, ils sont appelés individuellement lorsque vous écrivez aux fifos. Est-ce que j'oublie quelque chose?

  • Démarrez le programme de test dans une fenêtre de shell.
  • Write echo " abc " > testfifo1 dans la seconde fenêtre shell. - > rien ne se passe.
  • Écrire echo "quot" > testfifo2 dans une troisième fenêtre shell. - > maintenant je reçois " abc " et "def"
  • Écrivez à l'un des fifos. Ceci est immédiatement servi.

Modifier: La solution, comme le laisse entendre Gormley ci-dessous, était l'absence de non-blocage.

read_fd1 = open("testfifo1", O_RDONLY | O_NONBLOCK);
...
read_fd2 = open("testfifo2", O_RDONLY | O_NONBLOCK);

Cette modification du code ci-dessous l'a forcée à réagir immédiatement.

Le code:

#include <gtkmm/main.h>
#include <fcntl.h>
#include <iostream>

int read_fd1, read_fd2;
Glib::RefPtr<Glib::IOChannel> iochannel1, iochannel2;

// Usage: "echo "Hello" > testfifo<1|2>", quit with "Q"

bool MyCallback1(Glib::IOCondition io_condition)
{
    Glib::ustring buf;
    iochannel1->read_line(buf);
    std::cout << "io 1: " << buf;

    if (buf == "Q\n")
        Gtk::Main::quit();

    return true;
}

bool MyCallback2(Glib::IOCondition io_condition)
{
    Glib::ustring buf;
    iochannel2->read_line(buf);
    std::cout << "io 2: " << buf;

    if (buf == "Q\n")
        Gtk::Main::quit();

    return true;
}

int main(int argc, char *argv[])
{
    // the usual Gtk::Main object
    Gtk::Main app(argc, argv);

    if (access("testfifo1", F_OK) == -1)
    {
        if (mkfifo("testfifo1", 0666) != 0)
            return -1;
    }

    if (access("testfifo2", F_OK) == -1)
    {
        if (mkfifo("testfifo2", 0666) != 0)
            return -1;
    }

    read_fd1 = open("testfifo1", O_RDONLY);

    if (read_fd1 == -1)
        return -1;

    read_fd2 = open("testfifo2", O_RDONLY);

    if (read_fd2 == -1)
        return -1;

    Glib::signal_io().connect(sigc::ptr_fun(MyCallback1), read_fd1, Glib::IO_IN);
    Glib::signal_io().connect(sigc::ptr_fun(MyCallback2), read_fd2, Glib::IO_IN);

    iochannel1 = Glib::IOChannel::create_from_fd(read_fd1);
    iochannel2 = Glib::IOChannel::create_from_fd(read_fd2);

    app.run();

    if (unlink("testfifo1"))
        std::cerr << "error removing fifo 1" << std::endl;

    if (unlink("testfifo2"))
        std::cerr << "error removing fifo 2" << std::endl;

    return 0;
}
Était-ce utile?

La solution

Ces deux instructions empêchent le programme d'entrer dans la boucle principale jusqu'à ce que les deux fif sont ouverts à l'écriture. fifos bloquent jusqu'à ce que les deux côtés soient connectés

iochannel1 = Glib :: IOChannel :: create_from_fd (read_fd1); iochannel2 = Glib :: IOChannel :: create_from_fd (read_fd2);

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top