Si tengo dos instancias de Glib :: IOChannel, se bloquean hasta que ambas estén escritas. ¿Cuál es la forma correcta de hacer esto?

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

  •  20-08-2019
  •  | 
  •  

Pregunta

He modificado el ejemplo encontrado aquí para usar dos canales io. Parece que no se ha llamado a ninguna de las devoluciones de llamada antes de que haya escrito en ambos canales. Después de eso, se les llama individualmente cuando escriben a los fifos. ¿Estoy olvidando algo?

  • Inicie el programa de prueba en una ventana de shell.
  • Escribir echo " abc " > testfifo1 en la segunda ventana de shell. - > no pasa nada.
  • Escribir echo '' def '' > testfifo2 en una tercera ventana de shell. - > ahora obtengo " abc " y '' def ''
  • Escribe a uno de los fifos. Esto se sirve de inmediato.

Editar: La solución, como lo insinuó Gormley a continuación, fue la falta de no bloqueo.

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

Este cambio en el siguiente código hizo que respondiera de inmediato.

El código:

#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;
}
¿Fue útil?

Solución

Estas dos declaraciones impiden que el programa entre en el bucle principal hasta que ambos Están abiertos para escribir. bloque de fifos hasta que ambos lados estén conectados

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top