pthread_mutex_t的静态初始化

1 pthread_mutex_t的初始化

    第一种 使用宏PTHREAD_MUTEX_INITIALIZER进行初始化, 第二种 使用函数pthread_mutex_init函数。 区别:第一种方法仅局限于静态初始化的时候使用:将“声明”、“定义”、“初始化”一气呵成,除此之外的情况都只能使用pthread_mutex_init函数。

2 例子

#include <pthread.h>                                                                      
int main(int argc,char *argv[]) 

{ 

      pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; 

      pthread_mutex_t mutex2; 

      pthread_mutex_t mutex3; 

      mutex2 = PTHREAD_MUTEX_INITIALIZER; 

      mutex3 = mutex1; 

      return 0;  
}

编译错误如下:

lihai@lihai-linux:~/test$ g++ test8.cpp -o test8 -lpthread
test8.cpp: In function ‘int main(int, char**)’:
test8.cpp:12:14: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
       mutex2 = PTHREAD_MUTEX_INITIALIZER; 
              ^
//这里注意, mutex3的赋值是成功的。

3 原因

    在声明定义Mutex变量的时候进行初始化正是所谓的静态初始化的过程,而将Mutex变量声明之后,在后面的某条语句中对该Mutex变量进行首次赋值则不是静态初始化过程,不能使用宏的方式进行初始化。 Mutex3变量赋值,虽然能通过编译,但是POSIX指出,这种赋值的结果是未定的,所以应该禁止这种用法。 静态初始化过程就是编译器在编译的过程中完成了某些内存空间的初始化,也就是说这个初始化过程发生在编译时,而不是运行时,因此称之为静态初始化。PTHREAD_MUTEX_INITIALIZER 的完整定义为:
# define PTHREAD_MUTEX_INITIALIZER  

      { { 0, 0, 0, 0, 0, 0, { 0, 0 } } }

4 引申

上述问题并不仅仅针对于Mutex变量,而是所有的结构体变量。结构体变量在使用常量进行整体初始化的时候只能在声明定义的时候进行,不能是声明结束之后。以下为一段简单的测试代码:

#define POINT_INITIALIZER                                                                
 {
         
  0, 0}
typedef struct 

{ 
      int x,y; 

}point; 

int main(int argc,char *argv[]) 

{ 

      point x = POINT_INITIALIZER; 

      point y ; 

      y = POINT_INITIALIZER; 

      point z;

      z = x; 
      return 0; 
}

编译错误如下:

lihai@lihai-linux:~/test$ g++ test9.cpp -o test9 
test9.cpp: In function ‘int main(int, char**)’:
test9.cpp:2:7: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
  {
         
  0, 0}
       ^
test9.cpp:18:11: note: in expansion of macro ‘POINT_INITIALIZER’
       y = POINT_INITIALIZER; 
           ^
test9.cpp:18:9: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
       y = POINT_INITIALIZER; 
         ^
//实际上根据错误提示修改编译条件
g++ test9.cpp -o test9 -std=c++11
是可以直接编译通过。但这里应用了c++11 的 initializer list 特性。这里就不再讨论了。
经验分享 程序员 微信小程序 职场和发展