第三十八章 POSIX线程(二)
线程属性
初始化与销毁属性
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, ¶m);
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线程(二)的更多相关文章
- “全栈2019”Java第三十八章:类与方法
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- Gradle 1.12用户指南翻译——第三十八章. Eclipse 插件
本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- 第三十七章 POSIX线程(一)
POSIX线程库相关介绍 与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都有"pthread_"开头 要使用这些函数库,都需要加入头文件"<pth ...
- 第三十八章 springboot+docker(maven)
回顾上一章的整个部署过程: 使用"mvn install"进行打包jar 将jar移动到与Dockerfile文件相同的文件夹下 编写Dockerfile文件 使用"do ...
- 第三十四天- 线程队列、线程池(map/submit/shutdown/回调函数)
1.线程列队 queue队列 :使用import queue,用法与进程Queue一样 class queue.Queue(maxsize=0) # 先进先出: q = queue.Queue(3) ...
- 【第三十八章】 springboot+docker(maven)
回顾上一章的整个部署过程: 使用"mvn install"进行打包jar 将jar移动到与Dockerfile文件相同的文件夹下 编写Dockerfile文件 使用"do ...
- 【WPF学习】第三十八章 行为
样式提供了重用一组属性设置的实用方法.它们为帮助构建一致的.组织良好的界面迈出了重要的第一步——但是它们也是有许多限制. 问题是在典型的应用程序中,属性设置仅是用户界面基础结构的一小部分.甚至最基本的 ...
- 《剑指offer》第三十六题(二叉搜索树与双向链表)
// 面试题36:二叉搜索树与双向链表 // 题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求 // 不能创建任何新的结点,只能调整树中结点指针的指向. #include < ...
- SpringBoot | 第三十八章:基于RabbitMQ实现消息延迟队列方案
前言 前段时间在编写通用的消息通知服务时,由于需要实现类似通知失败时,需要延后几分钟再次进行发送,进行多次尝试后,进入定时发送机制.此机制,在原先对接银联支付时,银联的异步通知也是类似的,在第一次通知 ...
随机推荐
- 基于Tcp穿越的Windows远程桌面(远程桌面管理工具)
基于Tcp穿越的Windows远程桌面(远程桌面管理工具) 1.<C# WinForm 跨线程访问控件(实用简洁写法)> 2.<基于.NET环境,C#语言 实现 ...
- Windows下如何调试驱动程序
Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 一.配置Windbg使用双机调试 win10中“windbg+vm ...
- 我在用的翻译软件 -> 微软翻译+网易有道词典+谷歌翻译
Windows网页翻译 因为微软翻译相对来说翻译网页更为准确,我也喜欢用谷歌的Chrome浏览器,但是我没找到微软翻译的扩展,这里只能放弃 这个需要配合Microsoft Edge浏览器进行使用,也是 ...
- mpvue 页面预加载,新增preLoad生命周期
存在的必要性:mpvue开发微信小程序,在页面跳转到新页面的过程中会有200ms左右的延迟,这个200ms如果用来请求新页面的接口,那么跳转到新页面或许已经渲染好了页面. 就是两种方式: 1.新页面跳 ...
- Redis的几个核心机制底层原理
#### 1.S_DOWN和O_DOWN ###### S_DOWN和O_DOWN两种宕机状态 (1).S_DOWN是主观宕机,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机 s ...
- 线程池和lambda表达式
线程池1.什么是线程池.一个用来创建和管理线程的容器;2.线程池的作用.提高线程的复用性,降低资源消耗提高线程的响应速度,提高线程的可管理性3.线程的核心思想;线程的复用 4.线程池的创建Execut ...
- (19)ASP.NET Core EF创建模型(包含属性和排除属性、主键、生成的值)
1.什么是Fluent API? EF中内嵌的约定将POCO类映射到表.但是,有时您无法或不想遵守这些约定,需要将实体映射到约定指示外的其他对象,所以Fluent API和注解都是一种方法,这两种方法 ...
- fread优化读入
inline char nc() { static const int BS = 1 << 22; static unsigned char buf[BS],*st,*ed; if(st ...
- docker1-centos上安装docker
docker镜像(image)相当于面向对象的类 docker容器(container)相当于面向对象的对象 1.安装环境要求 目前,CentOS 仅发行版本中的内核支持 Docker. Docker ...
- windows下cmd组合命令和管道命令
组合命令:&& 管道命令:|