glib中gthread的应用---对核心应用的支持


对核心应用的支持

GLib对核心应用的支持包括事件循环、内存操作、线程操作、动态链接库的操作和出错处理与日志等。

下面代码演示了事件循环、内存操作、线程这三种功能的简单应用:

#include <glib.h>
static GMutex *mutex = NULL;
static gboolean t1_end = FALSE;
static gboolean t2_end = FALSE;
typedef struct _Arg Arg;
struct _Arg
{
	GMainLoop* loop;
	gint max;
};
void	run_1(Arg *arg)
{
	int i ;
	
	for(i=0; i<arg->max; i++)
	{
		if(g_mutex_trylock(mutex) == FALSE)
		{
			//g_print("%d : thread 2 locked the mutex \n", i);
			g_print("%d :线程2锁定了互斥对象\n", i);
			g_mutex_unlock(mutex);
		}
		else
		{
			g_usleep(10);
		}
	}
	t1_end = TRUE;
}
void	run_2(Arg *arg)
{
	int i;
	for(i=0; i<arg->max; i++)
	{
		if(g_mutex_trylock(mutex) == FALSE)
		{
			//g_print("%d : thread 1 locked mutex \n", i);
			g_print("%d :线程1锁定了互斥对象\n", i);
			g_mutex_unlock(mutex);
		}
		else
		{
			g_usleep(10);
		}
	}
	t2_end = TRUE;
}
void run_3(Arg *arg)
{
	for(;;)
	{
		if(t1_end && t2_end)
		{
			g_main_loop_quit(arg->loop);
			break;
		}
	}
}
int	main(int argc, char *argv[])
{
	GMainLoop *mloop;
	Arg *arg;
	
	if(!g_thread_supported())
		g_thread_init(NULL);
	mloop = g_main_loop_new(NULL, FALSE);
	
	arg = g_new(Arg, 1);
	arg->loop = mloop;
	arg->max = 11;
		
	mutex = g_mutex_new();
	g_thread_create(run_1, arg, TRUE, NULL);
	g_thread_create(run_2, arg, TRUE, NULL);
	g_thread_create(run_3, arg, TRUE, NULL);
	
	g_main_loop_run(mloop);
	g_print("线程3退出事件循环\n");
	g_mutex_free(mutex);
	g_print("释放互斥对象\n"); 
	g_free(arg);
	g_print("释放参数所用的内存\n");
}

Makefile文件如下:

CC = gcc
all:
	$(CC) `pkg-config --cflags --libs glib-2.0 gthread-2.0` loop.c -o loop
	

下面为输出结果:

0 :线程1锁定了互斥对象
1 :线程2锁定了互斥对象
2 :线程1锁定了互斥对象
3 :线程2锁定了互斥对象
4 :线程1锁定了互斥对象
5 :线程2锁定了互斥对象
6 :线程1锁定了互斥对象
7 :线程2锁定了互斥对象
8 :线程1锁定了互斥对象
9 :线程2锁定了互斥对象
10 :线程1锁定了互斥对象
线程3退出事件循环
释放互斥对象
释放参数所用的内存

以上例程创建了三个线程,其中run_1和run_2操作互斥对象,run_3检索前两个线程是否结束,如结束的话,则执行g_main_loop_quit退出事件循环。由于线程的运行是不确定的,所以不一定每次都是这一输出结果。

首先定义一个结构类型来保存创建的事件循环的对象指针和线程运行时的最多循环次数,一般情况下,如果为此数据结构来分配内存的话,用Arg *arg =(Arg*)malloc(sizeof(Arg));,释放时用free(arg);,这种传统的做法曾经让很多C语言的初学者头痛,尤其是需要多次操作的时候,GLib中提供了类似的函数g_malloc和g_free,最好用的方法是其将g_malloc函数封装成了宏g_new,这个宏有两个参数,第一个是结构类型,第二个是要分配结构的数量,这段代码中只用到了一个Arg数据结构,所以是g_new(Arg,1)。在程序结束时用g_free来释放。

在线程初始化时,首先是判断线程是否初始化的函数g_thread_supported,如果其返回FALSE则表明线程并未初始化,这时必须用g_thread_init来初始化,这是较明智的做法。

事件循环GMainLoop在用g_main_loop_new创建之后并不马上运行,用g_main_loop_run运行后,还要用g_main_loop_quit退出,否则循环将一直运行下去,这两个函数的参数都是GMainLoop型的指针,在主函数中并未直接运行g_main_loop_quit,而是把它放在线程的函数中了,这一点需读者注意。


参考链接:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值