线程属性

初始化与销毁属性

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. 关于Python json解析过程遇到的TypeError: expected string or buffer

    关于Python json解析过程遇到的问题:(爬取天气json数据所遇到的问题http://tianqi.2345.com/) part.1 url——http://tianqi.2345.com/ ...

  2. python正则表达式贪婪算法与非贪婪算法与正则表达式子模式的简单应用

    先引入一下百度百科对于正则表达式的概念: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种 ...

  3. 移动端适配 rem 设置

    refresh();    window.onresize = function(){      setTimeout(function(){        refresh();      },10) ...

  4. Javascript中Promise的简单使用

    // 函数功能:1秒以后创建一个10以内的随机整数,并判断这个数是否为偶数:如果是偶数则做一件事情,如果是奇数则做另一件事情 function doSomthing() { var promise = ...

  5. GIT原理介绍

    Git 是一套内容寻址文件系统.很不错.不过这是什么意思呢? 这种说法的意思是,Git 从核心上来看不过是简单地存储键值对(key-value).它允许插入任意类型的内容,并会返回一个键值,通过该键值 ...

  6. css3:bacground-size

    个人博客: https://chenjiahao.xyz CSS3之背景尺寸Background-size是CSS3中新加的一个有关背景的属性,这个属性是改变背景尺寸的通过各种不同是属性值改变背景尺寸 ...

  7. windows服务器多端口Redis安装步骤

    1.从官网获取最新稳定版redis文件.按端口号复制多个文件,比如6379和6380端口的文件包, 修改各自Conf文件的port号,分别为6379和6380.然后重命名为redis6379.conf ...

  8. RocketMQ事务消息学习及刨坑过程

    一.背景 MQ组件是系统架构里必不可少的一门利器,设计层面可以降低系统耦合度,高并发场景又可以起到削峰填谷的作用,从单体应用到集群部署方案,再到现在的微服务架构,MQ凭借其优秀的性能和高可靠性,得到了 ...

  9. Html中解决点击 a 标签刷新的问题,实现点击时不刷新

    Html中解决点击 a 标签刷新的问题 我们可以在 <a href=""></a>中,将地址属性href设置为“#” 例如 <a href=" ...

  10. Python 爬虫 爬取 煎蛋网 图片

    今天, 试着爬取了煎蛋网的图片. 用到的包: urllib.request os 分别使用几个函数,来控制下载的图片的页数,获取图片的网页,获取网页页数以及保存图片到本地.过程简单清晰明了 直接上源代 ...