文档章节

线程基本知识

o
 osc_z1hvg4cu
发布于 2018/04/24 21:59
字数 1376
阅读 0
收藏 0

精选30+云产品,助力企业轻松上云!>>>

  线程是程序中完成一个独立任务的完整执行序列,即一个可调度的实体。根据运行环境和调度者的身份,线程可分为内核线程和用户线程。

  1. 内核线程在有的系统上也称为LWP(Light Weight Process,轻量级进程),运行在内核空间,由内核来调度
  2. 用户线程运行在用户空间,由线程库来调度。

  当进程的一个内核线程获得CPU的使用权时,它就加载并运行一个用户线程。可见,内核线程相当于用户线程运行的“容器”。一个进程可以拥有M个内核线程和N个用户线程,其中M≤N.并且在一个系统的所有进程中,M和N的比值都是固定的。按照M:N的取值,线程的实现方式可分为三种模式:完全在用户空间实现、完全由内核调度和双层调度(two level scheduler)。

  完全在用户空间实现的线程无须内核的支持,内核甚至根本不知道这些线程的存在。线程库负责管理所有执行线程,比如线程的优先级、时间片等。线程库利用longimp来切换线程的执行,使它们看起来像是“并发”执行的。但实际上内核仍然是把整个进程作为最小单位来调度的。换句话说,进程的所有执行线程共义该进程的时间片,它们对外表现出相同的优先级。因此,对这种实现方式而言,N=1即M个用户空间线程对应1个内核线程,而该内核线程实际上就是进程本身。完全在用户空间实现的线程的优点是:创建和调度线程都无须内核的干预,因此速度相当快。并且由于它不占用额外的内核资源,所以即使一个进程创建了很多线程,也不会对系统性能造成明显的影响。其缺点是:对于多处理器系统,1个进程的多个线程无法运行在不同的CPU上,因为内核是按照其最小调度单位来分配CPU的。此外,线程的优先级只对同一个进程中的线程有效,比较不同进程中的线程的优先级没有意义。

  pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。

  unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join。

pthread_t://线程指针
pthread_attr_t://线程属性
pthread_mutex_t://互斥对象
pthread_mutexattr_t://互斥属性对象
pthread_cond_t://条件变量
pthread_condattr_t://条件属性对象
pthread_key_t://线程数据键
pthread_rwlock_t://读写锁
pthread_create()://创建一个线程
pthread_exit()://终止当前线程
pthread_cancel()://中断另外一个线程的运行
pthread_join()://阻塞当前的线程,直到另外一个线程运行结束
pthread_attr_init()://初始化线程的属性
pthread_attr_setdetachstate()://设置脱离状态的属性(决定这个线程在终止时是否可以被结合)
pthread_attr_getdetachstate()://获取脱离状态的属性
pthread_attr_destroy()://删除线程的属性
pthread_kill()://向线程发送一个信号
pthread_equal():// 对两个线程的线程标识号进行比较
pthread_detach(): //分离线程
pthread_self(): //查询线程自身线程标识号
pthread_detach(thread); //设置子线程的状态设置为detached,则该线程运行结束后会自动释放所有资源
 

线程属性

#include <pthread.h>

pthread_attr_t attr;
//函数的返回值都是:若成功则返回0,否则返回错误编号
int pthread_attr_init( pthread_attr_t *attr );
int pthread_attr_destroy( pthtread_attr_t *attr );

int pthread_attr_getdetachstate( const pthread_attr_t *restrict attr,int *detachstate );
int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate );

#ifdef _POSIX_THREAD_ATTR_STACKSIZE
int pthread_attr_getstacksize( const pthread_attr_t *restrict attr,size_t *restrict stacksize );
int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize );
#endif // _POSIX_THREAD_ATTR_STACKSIZE

#ifdef _POSIX_THREAD_ATTR_STACKADDR
int pthread_attr_setstackaddr( pthread_attr_t *attr, void *stackaddr);
int pthread_attr_setstackaddr( pthread_attr_t *attr, void **stackaddr);
#endif // _POSIX_THREAD_ATTR_STACKADDR

int pthread_getconcurrency( void );//返回值:当前的并发度
int pthread_setconcurrency( int level );//返回值:若成功则返回0,否则返回错误编号
  1.  设置堆栈大小不可移植,pthread定义PTHRAD_STACK_MIN,这指定每个线程要求最小栈大小
  2. 设置堆栈低地址不可移植,设置stackaddr属性时,为任何使用该属性的对象的线程指定一个存储器区域作为堆栈使用,栈至少要和PTHREAD_STACK_MIN一样大,再从上向下的栈空间的机器上,指定地址应该是栈的最高地址,而不是最低地址,如果栈增大,需要指定最低地址。
  3. 需要知道在写数据前或后,及其是否增加或减少栈——这决定了你指定的地址空间是否应该在分配的堆栈里面还是外边,系统不能告诉你是否分配了足够的空间,是否指定了正确的地址。
  4. 能够使用stackaddr的任何值创建一个线程,如果使用相同的stackaddr属性创建的两个并发线程,线程将在相同的栈上运行。
o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
【Java并发专题】27篇文章详细总结Java并发基础知识

努力的意义,就是,在以后的日子里,放眼望去全是自己喜欢的人和事! github:https://github.com/CL0610/Java-concurrency,欢迎题issue和Pull request。所有的文档都是自己亲自码的,如果觉...

你听___
2018/05/06
0
0
菜鸟之旅——学习线程(基础)

  在现在的软件编程中,不可避免的会用到多线程或者其他方式来实现异步的目的,那么,线程是个什么东西,如何使用?这些都是需要去学习与摸索的东西。不过在学习线程之前,还是有一些知识需...

osc_e4gzv47r
2018/02/12
0
0
线程

Java 并发编程:线程池的使用 Java 并发编程:线程池的使用 java 多线程核心技术梳理 (附源码) 本文对多线程基础知识进行梳理,主要包括多线程的基本使用,对象及变量的并发访问,线程间通信...

掘金官方
2018/01/12
0
0
【给初学者】Android学习路线

很多朋友都对学习路线问题感到迷茫,特别是还在上学的朋友们。在这里就详细的为大家介绍一下。 1.Java基础 很多朋友一上手就开始学习Android,似乎太着急了一些。Android应用程序开发是以Jav...

Jimmy Xie
2012/09/08
762
1
Java线程的周期及五种状态

线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程各重要知识点。掌握了上图中的各知识点,Java中的多线程也就基本...

osc_aesyur2z
2018/12/01
2
0

没有更多内容

加载失败,请刷新页面

加载更多

聊聊rocketmq-client-go的TraceInterceptor

序 本文主要研究一下rocketmq-client-go的TraceInterceptor TraceInterceptor rocketmq-client-go-v2.0.0/producer/interceptor.go // WithTrace support rocketmq trace: https://github.c......

go4it
38分钟前
0
0
如何在Android文本视图周围添加边框? - How do I put a border around an Android textview?

问题: 是否可以在textview周围绘制边框? 解决方案: 参考一: https://stackoom.com/question/EfXR/如何在Android文本视图周围添加边框 参考二: https://oldbug.net/q/EfXR/How-do-I-put...

法国红酒甜
53分钟前
10
0
设计模式(4) 建造者模式

什么是建造者模式 经典建造者模式的优缺点 对建造者模式的扩展 什么是建造者模式 建造者模式将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。创建者模式隐藏了...

zhixin9001
今天
14
0
ArrayList源码分析 —— JDK8

ArrayList的特性 ArrayList内部使用数据作为存储结构,ArrayList可以理解为数组的扩展对象,封装了常用的和非常用的操作数组的方法。以及当数组长度不足以保存数组时,自动扩容数组,通常Arr...

XuePeng77
今天
56
0
__slots__的用法? - Usage of __slots__?

问题: Python中__slots__的目的是什么-尤其是关于何时以及何时不使用它的目的? 解决方案: 参考一: https://stackoom.com/question/1ymu/slots-的用法 参考二: https://oldbug.net/q/1ym...

富含淀粉
今天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部