gpt4 book ai didi

c++ - 如何正确停止 g_main_loop_run?

转载 作者:行者123 更新时间:2023-12-02 10:20:43 30 4
gpt4 key购买 nike

我是第一次使用 GLib。因此,为了了解如何使用 GLib API,我编写了以下虚拟程序。

#include<glib.h>

#include<iostream>
#include<thread>
#include<chrono>

using namespace std;
using namespace std::chrono_literals;

class executor
{
private:
GMainLoop* main_loop;
GMainContext* worker_context;
thread worker_thread;

void worker_loop()
{
g_main_context_push_thread_default(worker_context);
cout << "Starting main loop" << endl;
g_main_loop_run(main_loop);
cout << "Finished main loop" << endl;
g_main_context_pop_thread_default(worker_context);
}

public:
executor()
{
worker_context = g_main_context_new();
main_loop = g_main_loop_new(worker_context, false);
worker_thread = thread(&executor::worker_loop, this);
}

~executor()
{
g_main_loop_quit(main_loop);
cout << "Stopped main loop from running" << endl;
g_main_loop_unref(main_loop);
g_main_context_unref(worker_context);
if (worker_thread.joinable())
{
worker_thread.join();
}
}

void queue_callback(int (*callback)(void))
{
GSource* idle_source = g_idle_source_new();
g_source_set_callback(idle_source, (GSourceFunc)callback, NULL, NULL);
g_source_attach(idle_source, worker_context);
g_source_unref(idle_source);
}
};

int func1()
{
cout << "func1 started" << endl;
this_thread::sleep_for(5s);
cout << "func1 finished waiting" << endl;
return 0;
}

int func2()
{
cout << "func2 started" << endl;
this_thread::sleep_for(1s);
cout << "func2 finished waiting" << endl;
return 0;
}

int main()
{
executor e;
e.queue_callback(func1);
e.queue_callback(func2);
return 0;
}

当我运行程序时,它没有完成执行,它卡住了。这是它打印的输出。
Stopped main loop from running
Starting main loop
func1 started
func1 finished waiting
func2 started
func2 finished waiting

有时它只是失败并出现以下错误
Stopped main loop from running
Starting main loop

(process:16343): GLib-CRITICAL **: 10:58:54.405: g_main_loop_run: assertion 'g_atomic_int_get (&loop->ref_count) > 0' failed
Finished main loop

我的猜测是这两个问题都发生了,因为 g_main_loop_quitg_main_loop_unref之前运行 g_main_loop_run .我该如何解决这些问题?

在 user7860670 的评论后编辑:
感谢 user7860670 的建议。这是现在的工作代码。
#include<glib.h>

#include<iostream>
#include<thread>
#include<chrono>

using namespace std;
using namespace std::chrono_literals;

class executor
{
private:
GMainLoop* main_loop;
GMainContext* worker_context;
thread worker_thread;

void worker_loop()
{
g_main_context_push_thread_default(worker_context);
cout << "Starting main loop" << endl;
g_main_loop_run(main_loop);
cout << "Finished main loop" << endl;
g_main_context_pop_thread_default(worker_context);
}

public:
executor()
{
worker_context = g_main_context_new();
main_loop = g_main_loop_new(worker_context, false);
worker_thread = thread(&executor::worker_loop, this);
}

~executor()
{
cout << "Stopping main loop" << endl;
GSource* idle_source = g_idle_source_new();
g_source_set_callback(idle_source, (GSourceFunc)g_main_loop_quit, main_loop, NULL);
g_source_attach(idle_source, worker_context);
g_source_unref(idle_source);

if (worker_thread.joinable())
{
worker_thread.join();
}
cout << "Removing references to main loop and context" << endl;

g_main_loop_unref(main_loop);
g_main_context_unref(worker_context);
}

void queue_callback(int (*callback)(void))
{
GSource* idle_source = g_idle_source_new();
g_source_set_callback(idle_source, (GSourceFunc)callback, NULL, NULL);
g_source_attach(idle_source, worker_context);
g_source_unref(idle_source);
}
};

int func1()
{
cout << "func1 started" << endl;
this_thread::sleep_for(5s);
cout << "func1 finished waiting" << endl;
return 0;
}

int func2()
{
cout << "func2 started" << endl;
this_thread::sleep_for(1s);
cout << "func2 finished waiting" << endl;
return 0;
}

int main()
{
executor e;
e.queue_callback(func1);
e.queue_callback(func2);
return 0;
}

最佳答案

它看起来像 executor e;可能会在工作线程开始工作之前超出范围,并且因为在 ~executor()您在等待工作线程之前取消引用循环和上下文对象,它们的引用计数下降到 0,并且它们在工作线程工作之前被销毁。您应该以其他方式执行此操作:WAITING工作线程完成,然后才取消引用循环和上下文对象。

关于c++ - 如何正确停止 g_main_loop_run?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60345245/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com