第三十八章 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实现消息延迟队列方案
前言 前段时间在编写通用的消息通知服务时,由于需要实现类似通知失败时,需要延后几分钟再次进行发送,进行多次尝试后,进入定时发送机制.此机制,在原先对接银联支付时,银联的异步通知也是类似的,在第一次通知 ...
随机推荐
- mysql数据库设计规则总结
MySQL数据库设计总结 规则1:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎. 注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的 ...
- CNN之yolo目标检测算法笔记
本文并不是详细介绍yolo工作原理以及改进发展的文章,只用做作者本人回想与提纲. 1.yolo是什么 输入一张图片,输出图片中检测到的目标和位置(目标的边框) yolo名字含义:you only lo ...
- 离线服务器安装zabbix
因为机房内的服务器并不是所有都能上外网,所以利用zabbix官方源的安装方法就行不通了,又嫌弃编译安装麻烦,所以这里选择离线RPM包安装zabbix.(如需完整rpm包可以留言与我联系) 下载zabb ...
- VR中的“寻路(wayfinding)”
虚拟现实(VR)中很重要的一个问题就是Locomotion(用户在VR中的移动).这个Locomotion分为两种,一种是点对点的,如传送门的方式,一种是包含了可以操控的中间过程的,这种被称为“导航( ...
- laravel基础操作手册
laravel基础操作手册 1.路由配置 测试配置路由: Route::get('/test', 'TestController@index'); 2.控制器书写 3.模型文件 4.增加扩展类文件 L ...
- 在Android开发中,当按下home键程序会完全退出时,解决这个BUG:
把这段代码贴到 super.onCreate(savedInstanceState); 之后 //remenber process if(!this.isTaskRoot()) { //判断该Act ...
- Akka实现WordCount(Scala)
Akka实现WordCount(Scala): 架构图: 项目结构: pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0 ...
- MongoDB 学习笔记之 Nested doc/DBRef (Spark)
Nested doc/DBRef (Spark) 实现: 运行结果:
- 纯CSS焦点轮播效果-功能可扩展
个人博客: http://mcchen.club 纯CSS3实现模拟焦点轮播效果,支持JQ等扩展各项功能.废话少说,直接贴代码. <!DOCTYPE html> <html> ...
- 第一次 在Java课上的编程
第一次在java课上的编程(使用参数输入求和): 代码: public class He { public static void main(String[] args) { ...