我有一个库,只公开了对流数据的阻塞ReadRead函数。现在我需要读取数据并在GTK3 GUI中显示。因此,我使用事务通道从运行Read到GUI线程的线程传递数据,然后通过g_idle_add读取var。显然这是错误的。应用程序导致CPU繁忙。正确的方法是什么?
伪代码:
idleAdd PRIORITY_DEFAULT_IDLE $ do
readTChan chan >>= \case
Nothing -> return SOURCE_CONTINUE
Just data -> show_data_in_textview data
forkIO $ loop $ do
theRead >>= writeTChan chan
答案 0 :(得分:4)
#include <gtkmm.h>
#include <string>
#include <iostream>
#include <thread>
#include <chrono>
#include <fcntl.h>
using namespace std::chrono_literals;
int main(int argc, char* argv[])
{
auto Application = Gtk::Application::create();
Gtk::Window window;
Gtk::ScrolledWindow scrolled;
Gtk::Box box(Gtk::ORIENTATION_VERTICAL) ;
window.add(scrolled);
scrolled.add(box);
window.show_all();
int pipeDescriptors[2];
pipe(pipeDescriptors);
bool keepAlive = true;
auto channel = Glib::IOChannel::create_from_fd(pipeDescriptors[0]);
channel->set_flags(Glib::IO_FLAG_NONBLOCK| Glib::IO_FLAG_IS_READABLE);
Glib::signal_io().connect([&](Glib::IOCondition ioCondition)->bool
{
std::cerr<<"condition: "<<ioCondition<<std::endl;
Glib::ustring fifoData;
channel->read_line(fifoData);
std::cerr<<"read: "<<fifoData<<std::endl;
auto label = new Gtk::Label(fifoData);
box.add(*label);
box.show_all();
return true;
}, channel, Glib::IO_IN);
auto thread = std::thread([&]{
while(keepAlive)
{
std::string buffer = "theRead()\n";
//it can also be char*. Newline is important because of read_line in the handler
write(pipeDescriptors[1], buffer.c_str(), buffer.size());
std::this_thread::sleep_for(1s);
}
});
window.signal_delete_event().connect([&](GdkEventAny* any_event)->bool{
keepAlive=false;
thread.join();
close(pipeDescriptors[1]); //let's start with input
close(pipeDescriptors[0]);
return false;
});
return Application->run(window);
}