简介
进程可以创建子进程,也可以执行外部程序。在不同平台上,子进程创建及执行外部程序的方法也不相同,GLib提供了一种跨平台的子进程创建接口。在linux上,执行外部程序最常见的是fork+exec方式。GLib提供了同步和异步两种方式创建子进程并执行外部程序。
数据结构
无
函数列表
gboolean g_spawn_async_with_pipes ()
gboolean g_spawn_async ()
gboolean g_spawn_sync ()
gboolean g_spawn_check_exit_status ()
gboolean g_spawn_command_line_async ()
gboolean g_spawn_command_line_sync ()
void g_spawn_close_pid ()
函数功能分类
// 异步执行一个子进程
gboolean g_spawn_async_with_pipes ()
gboolean g_spawn_async ()
// 同步执行一个子进程
gboolean g_spawn_sync ()
// 检查子进程状态
gboolean g_spawn_check_exit_status ()
// 对g_spawn_async()和g_spawn_sync()的封装,使用起来更方便
gboolean g_spawn_command_line_async ()
gboolean g_spawn_command_line_sync ()
// 关闭子进程(在linux系统上无任何效果)
void g_spawn_close_pid ()
函数功能说明及综合演示
同步创建子进程
本程序演示同步创建子进程,执行ls命令,并显示运行结果。
演示程序:
源码见glib_examples\glib_spawningproc\glib_spawning_proc_sync
#include <glib.h>
static void test_glib_spawning_proc_sync(void)
{
GPtrArray *argv = NULL;
gchar *stdout_str;
gchar *stderr_str;
gint estatus;
GError *error = NULL;
argv = g_ptr_array_new ();
g_ptr_array_add (argv, (gpointer)"/bin/ls");
g_ptr_array_add (argv, (gpointer)"-a");
g_ptr_array_add (argv, (gpointer)"-l");
g_ptr_array_add (argv, (gpointer)".");
g_ptr_array_add (argv, (gpointer)"file_not_exist");
g_ptr_array_add (argv, NULL);
g_spawn_sync (NULL, (char**)argv->pdata, NULL, G_SPAWN_DEFAULT, NULL, NULL, &stdout_str, &stderr_str, &estatus, &error);
g_assert_no_error (error);
g_print("%s \n", stdout_str);
g_print("%s \n", stderr_str);
g_free(stdout_str);
g_free(stderr_str);
g_ptr_array_free (argv, TRUE);
return;
}
gint main(gint argc, gchar **argv)
{
test_glib_spawning_proc_sync();
return 0;
}
运行结果:
[root@centos7_6 build]# ./glib_spawning_proc_sync
.:
总用量 40
drwxr-xr-x. 3 root root 120 2月 14 00:16 .
drwxr-xr-x. 3 root root 74 2月 14 00:15 ..
-rw-r--r--. 1 root root 12332 2月 14 00:15 CMakeCache.txt
drwxr-xr-x. 5 root root 250 2月 14 00:16 CMakeFiles
-rw-r--r--. 1 root root 1747 2月 14 00:15 cmake_install.cmake
-rwxr-xr-x. 1 root root 8752 2月 14 00:16 glib_spawning_proc_sync
-rw-r--r--. 1 root root 5580 2月 14 00:16 Makefile
/bin/ls: 无法访问file_not_exist: 没有那个文件或目录
多线程同步创建子进程
演示程序:
源码见glib_examples\glib_spawningproc\glib_spawning_proc_multi_thread_sync
#include <glib.h>
struct proc_data
{
const gchar *proc_path;
const gchar *proc_param;
};
static gpointer td_spawn_sync_multi_thread_instance (gpointer data)
{
GError *error = NULL;
GPtrArray *argv;
char *stdout_str;
char *stderr_str;
int estatus;
struct proc_data *pdata = (struct proc_data *) (data);
g_return_val_if_fail((NULL != data), NULL);
argv = g_ptr_array_new ();
g_ptr_array_add (argv, (gpointer)pdata->proc_path);
g_ptr_array_add (argv, (gpointer)pdata->proc_param);
g_ptr_array_add (argv, NULL);
g_printf("before spawn sync [%s %s]======================= \n", pdata->proc_path, pdata->proc_param);
g_spawn_sync (NULL, (char**)argv->pdata, NULL, G_SPAWN_DEFAULT, NULL, NULL, &stdout_str, &stderr_str, &estatus, &error);
g_assert_no_error (error);
g_printf("stdout_str=\n%s \n", stdout_str);
g_printf("stderr_str=\n%s \n", stderr_str);
g_printf("after spawn sync [%s %s]======================= \n", pdata->proc_path, pdata->proc_param);
g_free (stdout_str);
g_free (stderr_str);
g_ptr_array_free (argv, TRUE);
gchar c = (char)(pdata->proc_param[strlen(pdata->proc_param)-1]);
g_printf("c=%c \n", c);
return GINT_TO_POINTER (c);
}
static void td_multithreaded_test_single_run (GThread **thread, GThreadFunc function, struct proc_data *pdata)
{
g_return_if_fail(NULL != pdata);
g_return_if_fail(NULL != thread);
g_printf("path=%s param=%s\n", pdata->proc_path, pdata->proc_param);
*thread = g_thread_new(pdata->proc_path, function, (gpointer)pdata);
g_return_if_fail(NULL != thread);
}
static void td_spawn_sync_multi_thread (void)
{
GThread *thd1, *thd2, *thd3, *thd4;
gpointer ret1, ret2, ret3, ret4;
struct proc_data pdata1 = {"/bin/ls", "-a"};
td_multithreaded_test_single_run(&thd1, td_spawn_sync_multi_thread_instance, &pdata1);
struct proc_data pdata2 = {"/usr/bin/sleep", "2"};
td_multithreaded_test_single_run(&thd2, td_spawn_sync_multi_thread_instance, &pdata2);
struct proc_data pdata3 = {"/usr/bin/top", "-n 3"};
td_multithreaded_test_single_run(&thd3, td_spawn_sync_multi_thread_instance, &pdata3);
struct proc_data pdata4 = {"/bin/echo", "hello world"};
td_multithreaded_test_single_run(&thd4, td_spawn_sync_multi_thread_instance, &pdata4);
ret1 = g_thread_join(thd1);
ret2 = g_thread_join(thd2);
ret3 = g_thread_join(thd3);
ret4 = g_thread_join(thd4);
g_printf("ret1=%c ret2=%c ret3=%c ret4=%c \n", ret1 ,ret2, ret3, ret4);
return;
}
gint main (gint argc, gchar *argv[])
{
gint ret;
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/gthread/spawn-sync", td_spawn_sync_multi_thread);
ret = g_test_run();
return ret;
}
运行结果:
[root@centos7_6 glib_spawning_proc_multi_thread_sync]# ./glib_spawning_proc_multi_thread_sync
/gthread/spawn-sync: path=/bin/ls param=-a
path=/usr/bin/sleep param=2
path=/usr/bin/top param=-n 3
path=/bin/echo param=hello world
before spawn sync [/usr/bin/sleep 2]=======================
before spawn sync [/bin/ls -a]=======================
before spawn sync [/bin/echo hello world]=======================
before spawn sync [/usr/bin/top -n 3]=======================
stdout_str=
hello world
stderr_str=
after spawn sync [/bin/echo hello world]=======================
c=d
stdout_str=
.
..
CMakeCache.txt
CMakeFiles
cmake_install.cmake
CMakeLists.txt
glib_spawning_proc_multi_thread_sync
glib_spawning_proc_multi_thread_sync.c
Makefile
stderr_str=
after spawn sync [/bin/ls -a]=======================
c=a
stdout_str=
stderr_str=
top: failed tty get
after spawn sync [/usr/bin/top -n 3]=======================
c=3
stdout_str=
stderr_str=
after spawn sync [/usr/bin/sleep 2]=======================
c=2
ret1=a ret2=2 ret3=3 ret4=d
OK
异步创建子进程
本程序演示异步创建子进程,执行ls命令,并显示运行结果。
演示程序:
源码见glib_examples\glib_spawningproc\glib_spawning_proc_async
#include <glib.h>
static void test_glib_spawning_proc_async(void)
{
GPtrArray *argv = NULL;
GPid child_pid = 0;
GError *error = NULL;
argv = g_ptr_array_new ();
g_ptr_array_add (argv, (gpointer)"/bin/ls");
g_ptr_array_add (argv, (gpointer)"-a");
g_ptr_array_add (argv, (gpointer)"-l");
g_ptr_array_add (argv, (gpointer)".");
g_ptr_array_add (argv, (gpointer)"not_exist_file");
g_ptr_array_add (argv, NULL);
g_spawn_async(NULL, (char**)argv->pdata, NULL, G_SPAWN_DEFAULT, NULL, NULL, &child_pid, &error);
g_usleep (1*1000*1000);
g_assert_no_error (error);
g_spawn_close_pid(child_pid);
g_ptr_array_free (argv, TRUE);
return;
}
gint main(gint argc, gchar **argv)
{
test_glib_spawning_proc_async();
return 0;
}
运行结果:
[root@centos7_6 build]# ./glib_spawning_proc_async
/bin/ls: 无法访问not-exist-file: 没有那个文件或目录
.:
总用量 40
drwxr-xr-x. 3 root root 121 2月 14 00:07 .
drwxr-xr-x. 3 root root 75 2月 14 00:07 ..
-rw-r--r--. 1 root root 12340 2月 14 00:06 CMakeCache.txt
drwxr-xr-x. 5 root root 251 2月 14 00:07 CMakeFiles
-rw-r--r--. 1 root root 1750 2月 14 00:06 cmake_install.cmake
-rwxr-xr-x. 1 root root 8760 2月 14 00:07 glib_spawning_proc_async
-rw-r--r--. 1 root root 5621 2月 14 00:06 Makefile
同步创建子进程的简单方式
本程序演示使用简单方式同步创建子进程执行ls命令并显示运行结果。
演示程序:
源码见glib_examples\glib_spawningproc\glib_spawning_proc_sync_simple
#include <glib.h>
static void test_glib_spawning_proc_sync_simple(void)
{
gboolean ret = FALSE;
gchar *standard_output;
gchar *standard_error;
gint estatus;
GError *error = NULL;
ret = g_spawn_command_line_sync("/bin/ls -a -l . file_not_exist", &standard_output, &standard_error, &estatus, &error);
if(FALSE == ret) {
g_print("g_spawn_command_line_sync error! \n");
return;
}
g_print("%s \n", standard_output);
g_print("%s \n", standard_error);
g_free(standard_output);
g_free(standard_error);
return;
}
gint main(gint argc, gchar **argv)
{
test_glib_spawning_proc_sync_simple();
return 0;
}
运行结果:
[root@centos7_6 glib_spawning_proc_sync_simple]# ./glib_spawning_proc_sync_simple
.:
总用量 48
drwxr-xr-x. 3 root root 189 2月 14 00:20 .
drwxr-xr-x. 8 root root 225 2月 14 00:02 ..
-rw-r--r--. 1 root root 12370 2月 14 00:20 CMakeCache.txt
drwxr-xr-x. 5 root root 257 2月 14 00:20 CMakeFiles
-rw-r--r--. 1 root root 1756 2月 14 00:20 cmake_install.cmake
-rw-r--r--. 1 root root 907 2月 14 00:16 CMakeLists.txt
-rwxr-xr-x. 1 root root 8528 2月 14 00:20 glib_spawning_proc_sync_simple
-rw-r--r--. 1 root root 671 2月 14 00:16 glib_spawning_proc_sync_simple.c
-rw-r--r--. 1 root root 5843 2月 14 00:20 Makefile
/bin/ls: 无法访问file_not_exist: 没有那个文件或目录
异步创建子进程的简单方式
本程序演示使用简单方式异步创建子进程执行ls命令并显示运行结果。
演示程序:
源码见glib_examples\glib_spawningproc\glib_spawning_proc_async_simple
#include <glib.h>
static void test_glib_spawning_proc_async_simple(void)
{
gboolean ret = FALSE;
GError *error = NULL;
ret = g_spawn_command_line_async("/bin/ls -a -l", &error);
if(FALSE == ret) {
g_print("g_spawn_command_line_async return FALSE \n");
return;
}
g_print("test_glib_spawning_proc_async_simple exit \n");
return;
}
gint main(gint argc, gchar **argv)
{
test_glib_spawning_proc_async_simple();
g_print("main exit \n");
return 0;
}
运行结果:
[root@centos7_6 build]# ./glib_spawning_proc_async_simple
test_glib_spawning_proc_async_simple exit
main exit
[root@localhost build]# 总用量 40
drwxr-xr-x. 3 root root 128 2月 14 00:12 .
drwxr-xr-x. 3 root root 82 2月 14 00:09 ..
-rw-r--r--. 1 root root 12396 2月 14 00:09 CMakeCache.txt
drwxr-xr-x. 5 root root 258 2月 14 00:12 CMakeFiles
-rw-r--r--. 1 root root 1771 2月 14 00:09 cmake_install.cmake
-rwxr-xr-x. 1 root root 8496 2月 14 00:12 glib_spawning_proc_async_simple
-rw-r--r--. 1 root root 5908 2月 14 00:12 Makefile