pthread_once 一般用于一次性的线程初始化,在整个声明周期中,该方法只执行一次,从而实现一种线程安全的单例模式。
Pthread_once () 函数语法要点
头文件 : #include
函数原型 : int pthread_once(pthread_once_t *once_control, void(*int_routine)(void));
once_control : 一个静态或全局变量,初始化为 PTHREAD_ONCE_INT
init_routine : 初始化函数的函数指针
返回值:成功: 0 错误:错误码
LinuxThreads使用互斥锁和条件变量保证由pthread_once()指定的函数执行且仅执行一次,而once_control则表征是否执 行过。如果once_control的初值不是PTHREAD_ONCE_INIT(LinuxThreads定义为0),pthread_once() 的行为就会不正常。在LinuxThreads中,实际"一次性函数"的执行状态有三种:NEVER(0)、IN_PROGRESS(1)、DONE (2),如果once初值设为1,则由于所有pthread_once()都必须等待其中一个激发"已执行一次"信号,因此所有pthread_once ()都会陷入永久的等待中;如果设为2,则表示该函数已执行过一次,从而所有pthread_once()都会立即返回0。
[root@localhost 06]# cat pthread3.cpp
#include
#include
using namespace std;
pthread_once_t once = PTHREAD_ONCE_INIT;
void once_run(void)
{
cout<<"once_run in thread "<<(unsigned int )pthread_self()<
void * child1(void * arg)
{
pthread_t tid =pthread_self();
cout<<"thread "<<(unsigned int )tid<<" enter"<
cout<<"thread "<
void * child2(void * arg)
{
pthread_t tid =pthread_self();
cout<<"thread "<<(unsigned int )tid<<" enter"<
cout<<"thread "<
int main(void)
{
pthread_t tid1,tid2;
cout<<"hello"<
pthread_create(&tid2,NULL,child2,NULL);
sleep(10);
cout<<"main thread exit"<
}
[root@localhost 06]# g++ -lpthread pthread3.cpp -o pthread3
[root@localhost 06]# ./pthread3
hello
thread 3086535584 enter
once_run in thread 3086535584
thread 3086535584 return
thread 3076045728 enter
thread 3076045728 return
例子:muduo 网络库的 Singleton 就用到了 pthread_once。
templateclass Singleton : boost::nocopyable{ public: static T& instance(){ pthread_once(&ponce_,&Singleton::init); // 保证ponce_只会被执回调执行一次Singleton::init return *value_; } private: Singleton(); ~Singleton(); static void init(){ value_ = new T(); } private: static pthread_once_t ponce_; static T* value_; }; // 必须在头文件中定义static 变量 template pthread_once_t Singleton ::ponce_ = PTHREAD_ONCE_INIT; template T* Singleton ::value_ = NULL;
注意事项
在使用 pthread_once () 函数时需要注意,不能在其回调函数中调用 fork (),否则,当再次调用 pthread_once () 时,会在子进程中导致死锁。而且,不能在回调函数中抛出一个 C++异常。



