问题描述
如果我想运行,比如说 stty
,它控制终端设置(如逐字符或逐行),那么最好的方法是什么。我想使用 GTK+ 工具。创建一个新线程,然后从那个线程运行程序会更好……还是……?
解决方法
据我所知,GTK+ API 中有 7 个函数可以满足您列出的规范。其中 2 个是其中几个的子集。这是清单。
g_spawn_
g_thread_
g_task_
g_subprocess_
gdk_threads_
最后一个属于 GDK(Gimp Drawing Kit(为什么它有线程?)),其余的属于 GIO 和 Glib。以下是 g_thread_
和 g_subprocess_
的子集:
g_thread_pool_
g_subprocess_launcher_
您未能在上述问题中确定您是否希望 stty
独立于应用程序运行,或者说,连接到应用程序。
我现在将遍历上面提到的所有函数,并解释它们的用途。与往常一样,请查看 GTK+ 文档以获取 API 参考信息。一个显示 GTK+ 文档的好程序是 devhelp
。您可以通过在终端中输入:sudo apt install devhelp
来安装它。 (Linux)
g_spawn_
是一个 Glib 函数,用作 UNIX fork
和 exec
函数的更方便版本。它与进程的通信有限。在某些情况下,这正是您想要的,即运行一个程序,其输出实际上不必被扫描。如需更高级的版本,请查看 g_subprocess_
。
g_thread_
也属于 Glib。 (子)进程和线程之间的区别在于线程共享相同的地址空间,而(子)进程不共享(它们有自己的内存)。使用线程很好,因为它们之间很容易进行通信,但是你必须小心,否则会出现Heisenbugs。该函数支持 mutex-es(复数),防止竞争条件。使用线程的程序的一个例子是图像编辑器。一个线程处理鼠标移动,另一个处理效果的应用,另一个每隔一分钟左右写入自动保存信息。
g_thread_pool_
与 g_thread_
完全相同,不同之处在于它内置了对许多线程的处理。如果用 GTK+ 编写,浏览器(例如 Chromium 或 Opera)将使用此功能。每个线程将处理一个选项卡,然后由一个主线程管理(销毁和创建等)子线程。
g_task_
表示要执行的任务。它通常是异步的,但也可以是同步的。您调用 g_task_new()
并假定它是异步的,那么调用包含 g_task_new()
的函数的代码将恢复。您可以通过调用 g_task_return_
系列函数来指示任务已完成。然后回调函数被调用,到此结束。这与单独的线程具有基本相同的用途,当它被销毁时,会调用一个回调。
g_subprocess_
是一个更方便、更复杂的 g_spawn_
版本。与 Glib 生成相比,它的主要优势在于它的异步 I/O 能力:您可以从一个子进程的输出中读取,并处理输出,然后发送到另一个进程的输入流,而不会阻塞主循环。 g_spawn_
和其他 API 可以做到这一点,但难度更大。
gdk_threads_
本质上与 Glib 版本相同。唯一的区别在于单个数据结构实例的自动锁定。出于性能原因,g_thread_
不会这样做。但是您可以使用 g_thread_
手动锁定它们,而使用 gdk_threads_
则是自动完成的。但是因为 g_thread_
有更多的文档,所以最好使用它。
因此,您的问题的答案是使用 g_spawn_
。这是最简单的,当您编写程序时,您会尽量保持一切简单。