c-初始化:函数与文字



我注意到,在像libpthread这样的库中,会有一些结构可以通过以下两种方式之一进行分配。例如,pthread_mutex_t可以通过静态初始化

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

或通过动态

pthread_mutex_init(&lock);

但是,除非我遗漏了什么,否则pthread_mutex_init函数是多余的。也就是说,我就不能做吗

lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_init()的声明为:

int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);

因此,您可以通过函数调用向初始值设定项提供选定的属性,而不能通过使用PTHREAD_MUTEX_INITIALIZER的赋值来提供。

然而,如果您对默认属性感到满意,那么就没有明显的理由不能使用"复合文字"赋值表示法。

请注意,通过重新初始化赋值来"销毁"以前使用过的互斥体是不明智的。请始终使用pthread_mutex_destroy()函数来销毁互斥体。如果您正在为互斥对象使用一个局部变量,请确保在变量超出作用域之前总是将其销毁。并且不要在互斥体使用时破坏它。上面引用的POSIX页面涵盖了其中的许多要点。

也就是说,我不能只做吗

lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;

PTHREAD_MUTEX_INITIALIZER扩展为适用于在文件作用域声明的pthread_mutex_t类型对象的初始值设定项。这必须采用包含大括号的初始值设定项列表或与pthread_mutex_t兼容的类型的常量的形式。

  • 如果它是一个包含大括号的初始值设定项列表,则在它前面加上(pthread_mutex_t)将生成类型为pthread_mutex_t的复合文字。如果它不是数组类型,并且不直接或间接包含任何const成员,则C语言允许这样的赋值。

  • 如果它是一个与pthread_mutex_t兼容的类型的常量,则在它前面加上(pthread_mutex_t)将形成一个类型转换表达式,只有当pthread_mutex_t是void或标量类型时,C语言才允许这样做。在这一类别中,一个相当可能的替代方案是pthread_mutex_t是一种结构类型,PTHREAD_MUTEX_INITIALIZER扩展为复合文字,在这种情况下,强制转换将违反语言约束。

从C语言的角度来看,假设您可以执行这样的任务是不安全的。

从POSIX的角度来看,规范没有指定PTHREAD_MUTEX_INITIALIZER的扩展形式,也没有指定它适合您所描述的用途。因此,符合POSIX的C实现可以自由地使用他们想要的任何类型的内置或特殊外壳来实现它,并且不需要正确地处理除了用作初始化器之外的任何情况。

从这两个角度来看,不,按照你描述的那样做是不安全的。

此外,正如其他答案所观察到的,初始值设定项宏仅适用于您对默认互斥属性感到满意的情况。如果您想要非默认属性,例如健壮的或进程共享的互斥体,那么您必须使用pthread_mutex_init()来获取它们。尽管如此,不,pthread_mutex_init()不是多余的。

如果我没有弄错,函数会像一样声明

int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);

也就是说它有两个参数。

可以为已经存在的互斥体调用该函数,并且用户可以指定除默认互斥体属性之外的任何可接受的属性。

对于宏PTHREAD_MUTEX_INITIALIZER,则根据描述

在默认互斥属性合适的情况下,宏PTHREAD_MUTEX_INITIALIZER可用于初始化静态分配。效果相当于动态通过使用参数attr调用pthread_mutex_init((进行初始化指定为NULL,除非不执行错误检查

相关内容

  • 没有找到相关文章

最新更新