第三十八章 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实现消息延迟队列方案
前言 前段时间在编写通用的消息通知服务时,由于需要实现类似通知失败时,需要延后几分钟再次进行发送,进行多次尝试后,进入定时发送机制.此机制,在原先对接银联支付时,银联的异步通知也是类似的,在第一次通知 ...
随机推荐
- 关于Python json解析过程遇到的TypeError: expected string or buffer
关于Python json解析过程遇到的问题:(爬取天气json数据所遇到的问题http://tianqi.2345.com/) part.1 url——http://tianqi.2345.com/ ...
- python正则表达式贪婪算法与非贪婪算法与正则表达式子模式的简单应用
先引入一下百度百科对于正则表达式的概念: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种 ...
- 移动端适配 rem 设置
refresh(); window.onresize = function(){ setTimeout(function(){ refresh(); },10) ...
- Javascript中Promise的简单使用
// 函数功能:1秒以后创建一个10以内的随机整数,并判断这个数是否为偶数:如果是偶数则做一件事情,如果是奇数则做另一件事情 function doSomthing() { var promise = ...
- GIT原理介绍
Git 是一套内容寻址文件系统.很不错.不过这是什么意思呢? 这种说法的意思是,Git 从核心上来看不过是简单地存储键值对(key-value).它允许插入任意类型的内容,并会返回一个键值,通过该键值 ...
- css3:bacground-size
个人博客: https://chenjiahao.xyz CSS3之背景尺寸Background-size是CSS3中新加的一个有关背景的属性,这个属性是改变背景尺寸的通过各种不同是属性值改变背景尺寸 ...
- windows服务器多端口Redis安装步骤
1.从官网获取最新稳定版redis文件.按端口号复制多个文件,比如6379和6380端口的文件包, 修改各自Conf文件的port号,分别为6379和6380.然后重命名为redis6379.conf ...
- RocketMQ事务消息学习及刨坑过程
一.背景 MQ组件是系统架构里必不可少的一门利器,设计层面可以降低系统耦合度,高并发场景又可以起到削峰填谷的作用,从单体应用到集群部署方案,再到现在的微服务架构,MQ凭借其优秀的性能和高可靠性,得到了 ...
- Html中解决点击 a 标签刷新的问题,实现点击时不刷新
Html中解决点击 a 标签刷新的问题 我们可以在 <a href=""></a>中,将地址属性href设置为“#” 例如 <a href=" ...
- Python 爬虫 爬取 煎蛋网 图片
今天, 试着爬取了煎蛋网的图片. 用到的包: urllib.request os 分别使用几个函数,来控制下载的图片的页数,获取图片的网页,获取网页页数以及保存图片到本地.过程简单清晰明了 直接上源代 ...