glib里_GMutex类型

os posted @ 2013年9月23日 10:44 in Glib , 3490 阅读

不透明类型

不透明数据类型隐藏了它们内部格式或结构。在C语言中,它们就像黑盒一样。支持它们的语言不是很多。作为替代,开发者们利用typedef声明一个类型,把它叫做不透明类型,希望其他人别去把它重新转化回对应的那个标准C类型。通常开发者们在定义一套特别的接口时才会用到它们。比如说用来保存进程标识符的pid_t类型。该类型的实际长度被隐藏起来了——尽管任何人都可以偷偷撩开它的面纱,发现它就是一个int。如果所有代码都不显式的利用它的长度(显式利用长度这里指直接使用int类型的长度,比如说在编程时使用sizeof(int)而不是sizeof(pid_t)),那么改变时就不会引起什么争议,这种改变确实可能会出现:在老版本的Unix系统中,pid_t的定义是short类型。

另外一个不透明数据类型的例子是atomic_t。在第八章“内核同步方法”中介绍过,它放置的是一个可以进行原子操作的整型值。尽管这种类型就是一个int,但利用不透明类型可以帮助确保这些数据只在特殊的有关原子操作的函数中才会被使用。不透明类型还帮助我们隐藏了类型的长度,该类型也并不总是完整的32位。

内核还用到了其它一些不透明类型,包括dev_t,gid_t和uid_t等等。处理不透明类型时的原则是:

¨ 不要假设该类型的长度。

¨ 不要将该类型转化回其对应的C标准类型使用。

¨ 编程时要保证在该类型实际存储空间和格式发生变化时代码不受影响。

===================================================================
 
问:glib里_GMutex类型是在哪里定义的呀? 找了一圈没看到。

只看到个typedef sturct _GMutex GMutex;// glib/gthread.h P76 glib-2.29.10
 
答:The GMutex struct is an opaque data structure.
 
Opaque data types do not reveal their internal format or structure. They are about as "black box" as you can get in C. There is not a lot of language support for them. Instead, developers declare a typedef, call it an opaque type, and hope no one typecasts it back to a standard C type. All use is generally through a special set of interfaces that the developer creates.
 
See 《Linux_Kernel_Development_Second_Edition》or
Google "Opaque data type"
 
* Sometimes OPAQUE means "this function doesn't return anything at all",
similarly to "returns void" in C and some other languages.

* Sometimes OPAQUE means "this value can be any datatype at all" (eg,
input of the count() aggregate).

* Sometimes OPAQUE means "I know exactly what this should be, but it's
an internal datatype with no SQL-level equivalent". This is usually
what's at stake with a trigger function.

* Sometimes OPAQUE means "I know exactly what this should be, but I
haven't declared it yet" (ie, a forward reference). This is needed
to declare I/O functions of user-defined types, since the system
requires the functions to already exist when the type is declared.
 
如果声明了_GMutex,那么GMutex就变成了普通的结构,如果不声明他就是一个不透明类型。

再说,mutex类型是内核对象,必须定义在内核中,不依赖于系统是很难实现的。

不透明类型是一种灵活的类型,他的大小是未知的。所以一般只能定义GMutex *变量,不能定义GMutex对象。然后通过一套接口来操作GMutex,就是
代码:

struct _GThreadFunctions
{
GMutex* (*mutex_new) (void);

GMutex* (*mutex_lock) (void);
GMutex* (*mutex_trylock) (void);
GMutex* (*mutex_unlock) (void);

GMutex* (*mutex_free) (void);
/* .... */
};

下面是win32中对mutex_new 的实现
static GMutex * g_mutex_new_win32_cs_impl(void)
{
CRITICAL_SECTION * cs = g_new(CRITICAL_SECTION ,1);
gpointer * retval = g_new(gpointer, 1);
InitializeCriticalSection(cs);
*retval = cs;
return (GMutex *)retval;
}
// GMutex隐藏了实际具体平台相关的结构,相当于对用户统一表示,GMutex只是作为一种标示来使用,用户是不可见的。

这有点像C++的interface, 那一堆函数指针就是vtable。这张表要进行初始化,间接让他们指向操作系统提供的API。
所以就没有定义_GMutex必要,因为这份数据已经定义在系统核心中,我们只需要一个叫GMutex的名字来引用这份数据。

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter