pthread_once 语法

int	 pthread_once(pthread_once_t *once_control,

    void (*init_routine)(void));
#include <pthread.h>

pthread_once_t once_control = PTHREAD_ONCE_INIT;

int ret;

ret = pthread_once(&once_control, init_routine);

once_control 参数用来确定是否已调用相关的初始化例程。

pthread_once 返回值

pthread_once() 在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下情况,pthread_once() 将失败并返回相应的值。

EINVAL

描述:

once_control 或 init_routine 是 NULL

解析:

在多线程环境中,有些事仅需要执行一次。通常当初始化应用程序时,可以比较容易地将其放在main函数中。但当你写一个库时,就不能在main里面初始化了,你可以用静态初始化,但使用一次初始化(pthread_once)会比较容易些。

int pthread_once(pthread_once_t *once_control, void (*init_routine) (void));

功能:本函数使用初值为PTHREAD_ONCE_INIT的once_control变量保证init_routine()函数在本进程执行序列中仅执行一次。

在多线程编程环境下,尽管pthread_once()调用会出现在多个线程中,init_routine()函数仅执行一次,究竟在哪个线程中执行是不定的,是由内核调度来决定。

Linux Threads使用互斥锁和条件变量保证由pthread_once()指定的函数执行且仅执行一次,而once_control表示是否执行过。

如果once_control的初值不是PTHREAD_ONCE_INIT(Linux Threads定义为0),pthread_once() 的行为就会不正常。

在LinuxThreads中,实际"一次性函数"的执行状态有三种:NEVER(0)、IN_PROGRESS(1)、DONE (2),如果once初值设为1,则由于所有pthread_once()都必须等待其中一个激发"已执行一次"信号,因此所有pthread_once ()都会陷入永久的等待中;如果设为2,则表示该函数已执行过一次,从而所有pthread_once()都会立即返回0

#include<iostream>
#include<pthread.h>
using namespace std;  

pthread_once_t once = PTHREAD_ONCE_INIT;  

void once_run(void)
{
        cout<<"once_run in thread "<<(unsigned int )pthread_self()<<endl;
}  

void * child1(void * arg)
{
        pthread_t tid =pthread_self();
        cout<<"thread "<<(unsigned int )tid<<" enter"<<endl;
        pthread_once(&once,once_run);
        cout<<"thread "<<tid<<" return"<<endl;
}  

void * child2(void * arg)
{
        pthread_t tid =pthread_self();
        cout<<"thread "<<(unsigned int )tid<<" enter"<<endl;
        pthread_once(&once,once_run);
        cout<<"thread "<<tid<<" return"<<endl;
}  

int main(void)
{
        pthread_t tid1,tid2;
        cout<<"hello"<<endl;
        pthread_create(&tid1,NULL,child1,NULL);
        pthread_create(&tid2,NULL,child2,NULL);
        sleep();
        cout<<"main thread exit"<<endl;
        ;  

}  

结果:

hello
thread  enter
once_run
thread  return
thread  enter
thread  return
main thread exit 

pthread线程初始化(pthread_once)的更多相关文章

  1. [并发并行]_[线程模型]_[Pthread线程使用模型之三 客户端/服务端模型(Client/Server]

    Pthread线程使用模型之三 客户端/服务端模型(Client/Server) 场景 1.在客户端/服务端模型时,客户端向服务端请求一些数据集的操作. 服务端执行执行操作独立的(多进程或跨网络)– ...

  2. [并发并行]_[线程模型]_[Pthread线程使用模型之一管道Pipeline]

    场景 1.经常在Windows, MacOSX 开发C多线程程序的时候, 经常需要和线程打交道, 如果开发人员的数量不多时, 同时掌握Win32和pthread线程 并不是容易的事情, 而且使用Win ...

  3. 分布式缓存系统 Memcached 工作线程初始化

    Memcached采用典型的Master-Worker模式,其核心思想是:有Master和Worker两类进程(线程)协同工作,Master进程负责接收和分配任务,Worker进程负责处理子任务.当各 ...

  4. 分享一个关于pthread线程栈在mm_struct里面的分布问题

    大家好,本人被下面这个问题困扰了一段时间,最近似乎找到了答案. 这里和大家分享一下,可能对有相同困惑的同学有点帮助,同时也请各位帮忙看看错漏的地方. 1================问题: 在使用p ...

  5. 【C/C++多线程编程之四】终止pthread线程

    多线程编程之终止pthread线程       Pthread是 POSIX threads 的简称,是POSIX的线程标准.           终止线程似乎是多线程编程的最后一步,但绝不是本系列教 ...

  6. [并发并行]_[线程模型]_[Pthread线程使用模型之二 工作组work crew]

    Pthread线程使用模型之二工作组(Work crew) 场景 1.一些耗时的任务,比如分析多个类型的数据, 是独立的任务, 并不像 pipeline那样有序的依赖关系, 这时候pipeline就显 ...

  7. 【C/C++多线程编程之五】pthread线程深入理解

    多线程编程之pthread线程深入理解       Pthread是 POSIX threads 的简称,是POSIX的线程标准.           前几篇博客已经能给你初步的多线程概念.在进一步学 ...

  8. 【C/C++多线程编程之十】pthread线程私有数据

    多线程编程之线程私有数据      Pthread是 POSIX threads 的简称.是POSIX的线程标准.         线程同步从相互排斥量[C/C++多线程编程之六]pthread相互排 ...

  9. [转]c++多线程编程之pthread线程深入理解

    多线程编程之pthread线程深入理解         Pthread是 POSIX threads 的简称,是POSIX的线程标准.           前几篇博客已经能给你初步的多线程概念.在进一 ...

随机推荐

  1. Win10下安装Go开发环境

    关于Go语言有多么值得学习,这里就不做介绍了,既然看了这篇文章,想必是对有学习意向. 这里是在Windows下安装Go环境,去中文社区的下载栏目,https://studygolang.com/dl ...

  2. 再论Splay

    联赛前为了填知识点,简单学了一下比较常用的高级数据结构,都没有太深入的理解,于是现在重新搞一遍. 其实有了set和multiset,那么我们就没有再手写平衡树的必要了,所以treap的应用就相对于Sp ...

  3. 20145104张家明 《Java程序设计》第4周学习总结

    20145104张家明 <Java程序设计>第4周学习总结 教材学习内容总结 第六章 1.继承的定义及目的 面向对象中,子类继承父类,避免重复的行为定义.不过并非为了避免重复定义行为就使用 ...

  4. 20145122《Java程序设计》第6周学习总结

    教材学习内容总结 1.Java是以串流(Stream)的方式来处理输入与输出. 2.串流是一种抽象观念,从键盘输入资料,将处理结果输入档案,以及读取档案的内容等动作皆视为串流的处理. 3.在JAVA中 ...

  5. HDU 4272 LianLianKan (状压DP+DFS)题解

    思路: 用状压DP+DFS遍历查找是否可行.假设一个数为x,那么他最远可以消去的点为x+9,因为x+1~x+4都能被他前面的点消去,所以我们将2进制的范围设为2^10,用0表示已经消去,1表示没有消去 ...

  6. sqlite的时间筛选字段

    唉,需要不停的踩坑呀 commandText = commandText + string.Format("where [CollectDateTime] <'{0}' and [Co ...

  7. Redis之数据备份与恢复

    Redis 数据备份与恢复 Redis SAVE 命令用于创建当前数据库的备份. 语法 redis Save 命令基本语法如下: redis 127.0.0.1:6379> SAVE 实例 re ...

  8. (译)综合指南:通过Ubuntu 16.04上从Source构建来安装支持GPU的Caffe2

    (译)综合指南:通过Ubuntu 16.04上从Source构建来安装支持GPU的Caffe2 译者注: 原文来自:https://tech.amikelive.com/node-706/compre ...

  9. 51 Nod 1500 苹果曼和树(树形dp)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1500 思路: 树形dp. 我们考虑当前结点 i ,对于结点 i ,它可以 ...

  10. Validate Binary Search Tree,判断是否是二叉排序树

    算法分析:两种方法,一种是中序遍历,然后得到一个序列,看序列是否是有序的.第二种,是用递归. 中序遍历: public class Solution { List<Integer> lis ...