一、为什么要使用一次性初始化
    有些事需要且只能执行一次(比如互斥量初始化)。通常当初始化应用程序时,可以比较容易地将其放在main函数中。但当你写一个库函数时,就不能在main里面初始化了,你可以用静态初始化,但使用一次初始(pthread_once_t)会比较容易些。

二、如何进行一次性初始化
    1、首先要定义一个pthread_once_t变量,这个变量要用宏PTHREAD_ONCE_INIT初始化。然后创建一个与控制变量相关的初始化函数:

    pthread_once_t once_control = PTHREAD_ONCE_INIT;void init_routine(){//初始化互斥量//初始化读写锁......}

2、接下来就可以在任何时刻调用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()函数仅执行一次,究竟在哪个线程中执行是不定的,是由内核调度来决定。
    3、Linux Threads使用互斥锁和条件变量保证由pthread_once()指定的函数执行且仅执行一次。实际"一次性函数"的执行状态有三种:
        NEVER(0)、IN_PROGRESS(1)、DONE (2),用once_control来表示pthread_once()的执行状态:
     1)、如果once_control初值为0,那么 pthread_once从未执行过,init_routine()函数会执行。
    2)、如果once_control初值设为1,则由于所有pthread_once()都必须等待其中一个激发"已执行一次"信号, 因此所有pthread_once ()都会陷入永久 的等待中,init_routine()就无法执行
    3)、如果once_control设为2,则表示pthread_once()函数已执行过一次,从而所有pthread_once()都会立即   返回,init_routine()就没有机会执行,当pthread_once函数成功返回,once_control就会被设置为2。四、实例
1、一次性初始化的验证

/*DATE:            2015-4-15*AUTHOR:        DDDDD*DESCRIPTION:    一次性初始化int pthread_once(pthread_once_t* once_control, void (*init_routine)(void));如果once_control为0,init_routine()就会执行pthread_once()成功返回之后,once_control会变为2*/#include "apue.h"pthread_once_t once = 2;
pthread_t tid;void thread_init()
{printf("I'm in thread 0x%x\n", tid);}void *thread_fun1(void *arg)
{tid = pthread_self();printf("I'm thread 0x%x\n", tid);printf("once is %d\n", once);pthread_once(&once, thread_init);printf("once is %d\n", once);return NULL;
}void *thread_fun2(void *arg)
{sleep(2);tid = pthread_self();printf("I'm thread 0x%x\n", tid);pthread_once(&once, thread_init);return NULL;
}int main()
{pthread_t tid1, tid2;int err;err = pthread_create(&tid1, NULL, thread_fun1, NULL);if(err != 0){printf("create new thread 1 failed\n");return ;}err = pthread_create(&tid2, NULL, thread_fun2, NULL);if(err != 0){printf("create new thread 1 failed\n");return ;}pthread_join(tid1, NULL);pthread_join(tid2, NULL);return 0;
}

2、将互斥量的初始化,使用pthread_once来实现

/*DATA:            2015-4-20*AUTHOR;        WJ*DESCRIPTION:    使用多线程对一个队列进行增加和减少,增加操作是一个线程,删除操作是一个线程*    */
#include "apue.h"pthread_mutex_t mutex;
pthread_once_t once = PTHREAD_ONCE_INIT;struct queue{int len;int write_pos;int read_pos;int data[50];
};//互斥量初始化函数
void mutex_init()
{int err;err = pthread_mutex_init(&mutex, NULL);if(err){printf("mutex init failed\n");return;}
}//队列初始化
struct queue *queue_init()
{struct queue *que;//申请内存que = (struct queue *)malloc(sizeof(struct queue));if(que ==NULL){printf("malloc failed\n");return;}//初始化que->len = 0;que->write_pos = 0;que->read_pos = 0;return que;
}void queue_destroy(struct queue *que)
{//销毁互斥量和quepthread_mutex_destroy(&mutex);free(que);
}void *queue_add(void *arg)
{//对互斥量进行一次性初始化pthread_once(&once, mutex_init);struct queue *que = (struct queue *)arg;int buf=0;while(buf<50){pthread_mutex_lock(&mutex);que->data[que->write_pos] = buf;que->write_pos ++;que->len ++;buf++;printf("write data %d to queue\n", que->data[que->write_pos -1]);pthread_mutex_unlock(&mutex);sleep(1);}
}void *queue_del(void *arg)
{//    对互斥量进行一次性初始化pthread_once(&once, mutex_init);struct queue *que = (struct queue *)arg;int buf=0;while(1){sleep(2);pthread_mutex_lock(&mutex);buf = que->data[que->read_pos];que->read_pos ++;if(que->len -- == 0){printf("queue is empty\n");return;}buf++;printf("read data %d from queue\n", que->data[que->read_pos -1]);pthread_mutex_unlock(&mutex);}
}int main()
{pthread_t tid1, tid2;int err;struct queue *que;//队列初始化que = queue_init();err = pthread_create(&tid1, NULL, queue_add, (void *)que);if(err){printf("create add thread failed\n");queue_destroy(que);return;}err = pthread_create(&tid2, NULL, queue_del, (void *)que);if(err){printf("create del thread failed\n");queue_destroy(que);return;}//等待增加和删除操作完成pthread_join(tid1, NULL);pthread_join(tid2, NULL);//销毁queue_destroy(que);
}

linux下线程的一次性初始化相关推荐

  1. linux下线程错误码表

    linux下线程错误码在/usr/include/asm-generic/errno-base.h中查看

  2. linux下C结构体初始化

    引子 在看Linux netlink部分的时候看到了这样的写法 struct netlink_kernel_cfg cfg = {.groups = RTNLGRP_MAX,.input = rtne ...

  3. linux下线程池实现

    linux下线程池实现 转自:http://blog.csdn.net/lmh12506/article/details/7753952 前段时间在github上开了个库,准备实现自己的线程池的,因为 ...

  4. 简单实现Linux下线程池

    最近在Linux下使用mysql时有时会报查询异常,看网上解决方案是多次并发使用,通过gdb调试也找到问题,主要是上次查询结果集未释放,最终导致如此. 大佬说根本解决方案还是线程池,就去看了线程池的一 ...

  5. LINUX下线程默认栈大小的设置

    默认的大小(8M) linux下默认的栈可以通过以下命令查看 ulimit -s 如果没有更改过,默认的值为8192k = 8192/1024=8M 通过代码也可以查看, pthread_attr_i ...

  6. linux+分离线程+退出,Linux下线程终止操作.pdf

    Linux Linux LLiinnuuxx下线程的终止操作 简介: 简介: 简简介介:: 编写Linux下的多线程程序,需要使用头文件pthread.h, 编写Linux下的多线程程序,需要使用头文 ...

  7. Linux下线程(LWP)的相关概念

    一.概念 线程:一个进程内部的控制序列.或者说在一个程序里的一个执行路线 首先明确一个概念,在Linux下是没有进程的控制块的,使用进程模拟的线程.一个进程中至少有一个线程.所以进程跟线程的数量是一对 ...

  8. Linux下线程池源码实现

    线程池: 初始化阶段创建有最大数量限制的线程,以及一个线程安全的任务队列,若有任务需要处理,则将任务抛入线程池中,线程池中的的线程就会去处理这个任务. 优点 1.避免峰值压力下,资源耗尽的风险: 2. ...

  9. win10多核与linux多核,win10拖后腿,Linux下线程撕裂者处理器性能提升50%

    AMD的第二代Threadripper处理器已经发布两天了,其中的旗舰Threadripper 2990WX成为桌面处理器市场上首款32核64线程处理器,相关评测也发布了,大家能看到32核处理器在多核 ...

最新文章

  1. 社会生活中常用的14条著名法则
  2. EntityFramework:状态变化与方法的关系
  3. python—函数实例一
  4. IT兄弟连 JavaWeb教程 jQuery中其他AJAX支持的函数
  5. java的read()_Java Reader read()方法
  6. openCV视频处理与图像转换
  7. js $.ajax stop,jQuery.ajaxStop() 函数详解
  8. android 转场动画兼容问题,【Android】关于ARouter转场动画的问题
  9. 计算机等级考试机试试题,计算机等级考试二级VFP机试试题18
  10. SQLi LABS Less 16 布尔盲注
  11. h264码流文件通过计算first_mb_in_slice区分帧边界
  12. android 屏蔽焦点,android – 如何在视图失去焦点时屏蔽EditText中的文本.
  13. smartMeter
  14. lnmp无法删除.user.ini文件的解决办法
  15. 华硕笔记本BIOS设置禁用UEFI后使用U盘装系统方法
  16. 地理空间分析中的常用python操作
  17. 【软件测试】学习路线资料整理摆脱迷茫,突破瓶颈(送给我迷茫的朋友)
  18. html 复制链接功能,h5分享功能[通过复制网页链接分享]
  19. 知识库微信小程序开发
  20. shell awk监控磁盘使用率

热门文章

  1. 【Android 应用开发】AndroidUI设计 之 图片浏览器
  2. jQuery 轮播图
  3. 2017-2018-1 20155207 《信息安全系统设计基础》第四周学习总结
  4. SQL server与Oracle触发器的创建与使用
  5. 为什么我电脑进入睡眠后网络就断开了?(解决打开睡眠后的笔记本无法连接校园网的问题)
  6. 搞笑视频分析---2、爱做饭的芋头:手搓冰粉
  7. NOIP 2017 d2t2 70points
  8. android - 拍照
  9. .net工具类 分享一个简单的随机分红包的实现方式
  10. 规范-编码规范总结(微信分销系统)