Se eu tiver duas instâncias do Glib :: IOChannel, eles bloquear até que ambos escritos. Qual é a maneira correta de fazer isso?

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

  •  20-08-2019
  •  | 
  •  

Pergunta

Eu modifiquei o exemplo encontrado aqui usar dois canais io. Nenhum dos retornos de chamada parecem ser chamado antes de eu ter escrito para ambos os canais. Depois que eles são chamados individualmente ao escrever aos fifos. Am I esquecendo de algo?

  • Inicie o programa de teste em uma janela shell.
  • Write echo "abc"> testfifo1 na segunda janela shell. -.> Nada acontece
  • Write echo "def"> testfifo2 em uma janela do terceiro shell. -> agora eu recebo "abc" e "def"
  • Write a um dos fifos. Esta é imediatamente servido.

Edit: A solução, como sugerido por Gormley abaixo, foi a falta de nonblock.

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

Esta alteração ao código abaixo tornou responder imediatamente.

O 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;
}
Foi útil?

Solução

Estas duas declarações bloquear o programa de entrar no loop principal até que ambos os fifos estão abertos para gravação. fifos bloquear até que ambos os lados estão conectados

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top