3_18_GLib库入门与实践_进程创建

简介

进程可以创建子进程,也可以执行外部程序。在不同平台上,子进程创建及执行外部程序的方法也不相同,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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值