线程属性

初始化与销毁属性

int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);

获取与设置分离属性

int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); detachstate :
PTHREAD_CREATE_DETACHED
PTHREAD_CREATE_JOINABLE

获取与设置栈大小

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);

获取与设置栈溢出保护区大小

int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize);

获取与设置线程竞争范围

int pthread_attr_setscope(pthread_attr_t *attr, int scope);
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope); scope :
PTHREAD_SCOPE_SYSTEM
PTHREAD_SCOPE_PROCESS

获取与设置调度策略

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy); policy :
SCHED_FIFO : 如果线程优先级相同,按照先进先出的原则来调度
SCHED_RR : 如果线程优先级相同,按照抢占式的原则来调度
SCHED_OTHER : 其它情况

获取与设置继承的调度策略

int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched); inheritsched :
PTHREAD_INHERIT_SCHED
PTHREAD_EXPLICIT_SCHED

获取与设置调度参数

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param); struct sched_param {
int sched_priority; /* Scheduling priority 调度优先级*/
};

获取与设置并发级别

int pthread_setconcurrency(int new_level);
int pthread_getconcurrency(void);

  仅在N:M线程模型中,设置并发级别,给内核一个提示;表示提供给定级别数量的核心线程来映射用户线程是高效的。

  默认是0,表示内核按照自己合适的规则来映射

pthread_attr.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h> #define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0) int main(void)
{
pthread_attr_t attr;
pthread_attr_init(&attr); int state;
pthread_attr_getdetachstate(&attr, &state);
if(state == PTHREAD_CREATE_JOINABLE)
printf("state : PTHREAD_CREATE_JOINABLE\n");
else if(state == PTHREAD_CREATE_DETACHED)
printf("state : PTHREAD_CREATE_DETACHED"); size_t size;
pthread_attr_getstacksize(&attr, &size);
printf("stacksize : %lu\n",size); size_t guardsize;
pthread_attr_getguardsize(&attr, &guardsize);
printf("guardsize : %lu\n",guardsize); int scope;
pthread_attr_getscope(&attr, &scope);
if(scope == PTHREAD_SCOPE_PROCESS)
printf("scope : PTHREAD_SCOPE_PROCESS\n");
else if(scope == PTHREAD_SCOPE_SYSTEM);
printf("scope : PTHREAD_SCOPE_SYSTEM\n"); int policy;
pthread_attr_getschedpolicy(&attr, &policy);
if(policy == SCHED_FIFO)
printf("policy : SCHED_FIFO\n");
else if(policy == SCHED_RR)
printf("policy : SCHED_RR\n");
else if(policy == SCHED_OTHER)
printf("policy : SCHED_OTHER\n"); int inheritsched;
pthread_attr_getinheritsched(&attr, &inheritsched);
if(inheritsched == PTHREAD_EXPLICIT_SCHED)
printf("inheritsched : PTHREAD_EXPLICIT_SCHED\n");
else if(inheritsched == PTHREAD_INHERIT_SCHED)
printf("inheritsched : PTHREAD_INHERIT_SCHED\n"); struct sched_param param;
pthread_attr_getschedparam(&attr, &param);
printf("sched_param : %d\n",param.__sched_priority); pthread_attr_destroy(&attr); int level;
level = pthread_getconcurrency();
printf("level : %d\n", level); return 0;
}

线程特定数据

  • 在单线程程序中,我们经常要用到“全局变量”以实现多个函数间共享数据
  • 在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程共有。
  • 但有时应用程序设计中有必要提供线程私有的全局变量,仅在某个线程中有效,但却可以跨多个函数访问
  • POSIX线程库通过维护一定的数据结构来解决这个问题,这些数据称为(Thread-specific Data, 或TSD)

pthread_key_create

功能:
从TSD池中分配一项,将其值赋给key供以后访问使用(每个线程都有128个key)
原型:
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
参数:
key : thread-specific data
destructor : 如果destructor不为空,在线程退出(pthread_exit())时将以key所关联的数据为参数调用destructor,以释放分配的缓冲区。
返回值:
成功 : 将创建的键值存放到key,返回0
失败 : 返回错误码

pthread_key_delete

功能:
删除一个key
原型:
int pthread_key_delete(pthread_key_t key);
参数:
key : thread-specific data
返回值:
成功 : 将创建的键值存放到key,返回0
失败 : 返回错误码

pthread_getspecific

功能:
获取线程特定数据
原型:
void *pthread_getspecific(pthread_key_t key);
参数:
key : thread-specific data
返回值:
成功 : 返回线程特定数据
失败 : NULL

pthread_setspecific

功能:
获取线程特定数据
原型:
int pthread_setspecific(pthread_key_t key, const void *value);
参数:
key : thread-specific data
value : 要设置的线程特定数据
返回值:
成功 : 0
失败 : 错误码

pthread_once

功能:
使用初值为PTHREAD_ONCE_INIT的once_control变量保证init_routine()函数在本进程执行序列中仅执行一次
原型:
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
pthread_once_t once_control = PTHREAD_ONCE_INIT;
参数:
once_control : 表示是否执行过
init_routine : 线程执行函数
返回值:
成功 : 0
失败 : 错误码

pthread_key.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h> #define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0) typedef struct tsd
{
pthread_t tid;
char *str;
}tsd_t; pthread_key_t key_tsd;
pthread_once_t once_control = PTHREAD_ONCE_INIT; void destructor_toutime(void* value)
{
printf("destory ...\n");
free(value);
} void init_routine(void)
{
pthread_key_create(&key_tsd, destructor_toutime);
printf("key init success\n");
} void* thread_routine(void *arg)
{
//保证只有一个线程会去调用init_routine,具体哪一个是不确定的
pthread_once(&once_control,init_routine); tsd_t *value = (tsd_t*)malloc(sizeof(tsd_t));
value->tid = pthread_self();
value->str = (char*)arg; pthread_setspecific(key_tsd, value); printf("%s setspecific %p\n", (char*)arg, value); value = pthread_getspecific(key_tsd);
printf("%s id : %lu str : %s\n",(char*)arg, value->tid, value->str); sleep(2); value = pthread_getspecific(key_tsd);
printf("%s id : %lu str : %s\n",(char*)arg, value->tid, value->str); return NULL;
} int main(void)
{
//在主线程中创建key
// pthread_key_create(&key_tsd, destructor_toutime); pthread_t tid1,tid2;
pthread_create(&tid1, NULL, thread_routine, "thread1");
pthread_create(&tid2, NULL, thread_routine, "thread2"); pthread_join(tid1, NULL);
pthread_join(tid2, NULL); pthread_key_delete(key_tsd);
return 0;
}

第三十八章 POSIX线程(二)的更多相关文章

  1. “全栈2019”Java第三十八章:类与方法

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  2. Gradle 1.12用户指南翻译——第三十八章. Eclipse 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  3. 第三十七章 POSIX线程(一)

    POSIX线程库相关介绍   与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都有"pthread_"开头   要使用这些函数库,都需要加入头文件"<pth ...

  4. 第三十八章 springboot+docker(maven)

    回顾上一章的整个部署过程: 使用"mvn install"进行打包jar 将jar移动到与Dockerfile文件相同的文件夹下 编写Dockerfile文件 使用"do ...

  5. 第三十四天- 线程队列、线程池(map/submit/shutdown/回调函数)

    1.线程列队 queue队列 :使用import queue,用法与进程Queue一样 class queue.Queue(maxsize=0) # 先进先出: q = queue.Queue(3) ...

  6. 【第三十八章】 springboot+docker(maven)

    回顾上一章的整个部署过程: 使用"mvn install"进行打包jar 将jar移动到与Dockerfile文件相同的文件夹下 编写Dockerfile文件 使用"do ...

  7. 【WPF学习】第三十八章 行为

    样式提供了重用一组属性设置的实用方法.它们为帮助构建一致的.组织良好的界面迈出了重要的第一步——但是它们也是有许多限制. 问题是在典型的应用程序中,属性设置仅是用户界面基础结构的一小部分.甚至最基本的 ...

  8. 《剑指offer》第三十六题(二叉搜索树与双向链表)

    // 面试题36:二叉搜索树与双向链表 // 题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求 // 不能创建任何新的结点,只能调整树中结点指针的指向. #include < ...

  9. SpringBoot | 第三十八章:基于RabbitMQ实现消息延迟队列方案

    前言 前段时间在编写通用的消息通知服务时,由于需要实现类似通知失败时,需要延后几分钟再次进行发送,进行多次尝试后,进入定时发送机制.此机制,在原先对接银联支付时,银联的异步通知也是类似的,在第一次通知 ...

随机推荐

  1. 基于Tcp穿越的Windows远程桌面(远程桌面管理工具)

    基于Tcp穿越的Windows远程桌面(远程桌面管理工具) 1.<C# WinForm 跨线程访问控件(实用简洁写法)>            2.<基于.NET环境,C#语言 实现 ...

  2. Windows下如何调试驱动程序

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 一.配置Windbg使用双机调试 win10中“windbg+vm ...

  3. 我在用的翻译软件 -> 微软翻译+网易有道词典+谷歌翻译

    Windows网页翻译 因为微软翻译相对来说翻译网页更为准确,我也喜欢用谷歌的Chrome浏览器,但是我没找到微软翻译的扩展,这里只能放弃 这个需要配合Microsoft Edge浏览器进行使用,也是 ...

  4. mpvue 页面预加载,新增preLoad生命周期

    存在的必要性:mpvue开发微信小程序,在页面跳转到新页面的过程中会有200ms左右的延迟,这个200ms如果用来请求新页面的接口,那么跳转到新页面或许已经渲染好了页面. 就是两种方式: 1.新页面跳 ...

  5. Redis的几个核心机制底层原理

    #### 1.S_DOWN和O_DOWN ######   S_DOWN和O_DOWN两种宕机状态  (1).S_DOWN是主观宕机,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机 s ...

  6. 线程池和lambda表达式

    线程池1.什么是线程池.一个用来创建和管理线程的容器;2.线程池的作用.提高线程的复用性,降低资源消耗提高线程的响应速度,提高线程的可管理性3.线程的核心思想;线程的复用 4.线程池的创建Execut ...

  7. (19)ASP.NET Core EF创建模型(包含属性和排除属性、主键、生成的值)

    1.什么是Fluent API? EF中内嵌的约定将POCO类映射到表.但是,有时您无法或不想遵守这些约定,需要将实体映射到约定指示外的其他对象,所以Fluent API和注解都是一种方法,这两种方法 ...

  8. fread优化读入

    inline char nc() { static const int BS = 1 << 22; static unsigned char buf[BS],*st,*ed; if(st ...

  9. docker1-centos上安装docker

    docker镜像(image)相当于面向对象的类 docker容器(container)相当于面向对象的对象 1.安装环境要求 目前,CentOS 仅发行版本中的内核支持 Docker. Docker ...

  10. windows下cmd组合命令和管道命令

    组合命令:&& 管道命令:|