莫斯科的景点有哪些:[百度分享]用户态线程库(1)
来源:百度文库 编辑:九乡新闻网 时间:2024/10/06 00:09:01
前言
我们编写的绝大多数程序都需要涉及到多线程的并发编程,一般情况下都是采用glibc提供的线程库进行开发。
这里从线程库的实现上来考虑对于并发情况下的编程模式。
从线程说起
线程是什么?
我们的多数程序都是运行在多线程模式下,通过同时并发处理多个任务来处理不同的请求。线程的特点是共享地址空间,从而高效的共享数据。与进程相比最大特点在于对于共享空间的简单处理,虽然进程间的数据共享采用mmap方式也很方便,但是毕竟涉及到共享内存的使用,需要有一定的注意,和使用要求。 多线程的概念引入,可以使得我们在一个进程中可以同时处理多个业务逻辑,而不受影响(共享数据有同步原语支持)。在多核环境下也可以有效的利用多CPU的优势。
本质上来说, 线程在实现上采用clone的调用方式利用在堆空间上分配的内存作为,每个线程的栈空间(我们的环境中是10M或者8M,采用ulimt -s 可以看到)都是独立,包含了当前CPU的信息。目前常用的是2.6内核(部分32位机器运行在2.4内核下),2.4内核中是采用进程来模拟线程,用ps命令可以看到有许多个进程,在ps命令看来,线程基本上是等同于进程。2.6内核中一个多线程的进程,只会显示一个进程,但用gdb 或者 pstack 查看程序依然可以看到
pthread_t 的意义, pthread_create创建线程的时候我们会拿到一个pthread_t 的返回值,在ullog中拿他做为线程号的标记,这个值本质上是维护线程数据的指针地址。 在ullog中采用这个作为线程的标记其实是存在问题的,假设这样的情况: 一个现程在启动后运行一段时间才退出,而后再启动,这个时候这个线程的数据依然会被复用,这个时候就出现了前后这两个在我们概念中是不一样的两个线程被认为是线程号相同的情况. 虽然我们在线程启动和结束的时候都会有标记特殊的日志
我们的glibc pthread的实现中,默认栈空间是10M(一些机器上是8M),这些可以在线程启动的时候进行修改。栈空间本质上也是通过mmap的方式从堆上分配出来提供给没个线程独立使用。在具体的实现上,栈与栈之间一般都会存在一部分空间是不可写同时也不可读的,这也是为什么我们一旦栈溢出就很容易出core的原因。 栈空间的大小可以在线程启动的时候修改或者通过ulimit方式进行强制的改变。
注:如果不考虑进程的可写数据(只读都是一样)的共享,多进程方式对比多线程其实优势更大,而且还有良好的安全性。
线程调度
在线程库中对于线程的分配一般是受到内存大小的控制, 而CPU的数量往往不多, 这里CPU在运行的时候就涉及到,如何去运作这些线程。每个线程只有获得CPU的使用权才能执行指令.所谓的多线程的并发运行,从 宏观上看.其实就是各个线程轮流或者CPU的使用权,分别执行各自的任务.在可运行池中,会有多个处于就绪状态的线程在等待CPU。
在我们使用的线程库中,调度往往需要考虑下面的方式
时间片,每个线程CPU运行一段时间后,主动让出CPU
阻塞或休眠, 比如sleep, 等待锁,系统调用等操作本身会让CPU出现一定程度上的上下文切换
线程结束
主动放弃CPU, 在我们的环境中是sched_yield, 可以主动让出CPU。
在我们现在64位机器上使用的都是基于nptl线程库,相比32位中2.4内核下的linuxthread本身有很的大的提高。基本的切换上相差了近1倍。
虽然操作系统中已经考虑了不少调度的问题,但是这些是实际中的表现往往不尽人意
时间片不可控,一些CPU消耗性程序其实可以多运行一部分时间
上下文切换有一定的内核态用户态的切换。
大量的锁应用, 对性能会带来一定的影响
当存在大量长时间堵塞的时候, 需要大量的线程支持, 会对系统产生负面影响
这样的基础上,我们考虑采用一些其他方式来解决这些问题, 比如异步编程。
我们编写的绝大多数程序都需要涉及到多线程的并发编程,一般情况下都是采用glibc提供的线程库进行开发。
这里从线程库的实现上来考虑对于并发情况下的编程模式。
从线程说起
线程是什么?
我们的多数程序都是运行在多线程模式下,通过同时并发处理多个任务来处理不同的请求。线程的特点是共享地址空间,从而高效的共享数据。与进程相比最大特点在于对于共享空间的简单处理,虽然进程间的数据共享采用mmap方式也很方便,但是毕竟涉及到共享内存的使用,需要有一定的注意,和使用要求。 多线程的概念引入,可以使得我们在一个进程中可以同时处理多个业务逻辑,而不受影响(共享数据有同步原语支持)。在多核环境下也可以有效的利用多CPU的优势。
本质上来说, 线程在实现上采用clone的调用方式利用在堆空间上分配的内存作为,每个线程的栈空间(我们的环境中是10M或者8M,采用ulimt -s 可以看到)都是独立,包含了当前CPU的信息。目前常用的是2.6内核(部分32位机器运行在2.4内核下),2.4内核中是采用进程来模拟线程,用ps命令可以看到有许多个进程,在ps命令看来,线程基本上是等同于进程。2.6内核中一个多线程的进程,只会显示一个进程,但用gdb 或者 pstack 查看程序依然可以看到
pthread_t 的意义, pthread_create创建线程的时候我们会拿到一个pthread_t 的返回值,在ullog中拿他做为线程号的标记,这个值本质上是维护线程数据的指针地址。 在ullog中采用这个作为线程的标记其实是存在问题的,假设这样的情况: 一个现程在启动后运行一段时间才退出,而后再启动,这个时候这个线程的数据依然会被复用,这个时候就出现了前后这两个在我们概念中是不一样的两个线程被认为是线程号相同的情况. 虽然我们在线程启动和结束的时候都会有标记特殊的日志
我们的glibc pthread的实现中,默认栈空间是10M(一些机器上是8M),这些可以在线程启动的时候进行修改。栈空间本质上也是通过mmap的方式从堆上分配出来提供给没个线程独立使用。在具体的实现上,栈与栈之间一般都会存在一部分空间是不可写同时也不可读的,这也是为什么我们一旦栈溢出就很容易出core的原因。 栈空间的大小可以在线程启动的时候修改或者通过ulimit方式进行强制的改变。
注:如果不考虑进程的可写数据(只读都是一样)的共享,多进程方式对比多线程其实优势更大,而且还有良好的安全性。
线程调度
在线程库中对于线程的分配一般是受到内存大小的控制, 而CPU的数量往往不多, 这里CPU在运行的时候就涉及到,如何去运作这些线程。每个线程只有获得CPU的使用权才能执行指令.所谓的多线程的并发运行,从 宏观上看.其实就是各个线程轮流或者CPU的使用权,分别执行各自的任务.在可运行池中,会有多个处于就绪状态的线程在等待CPU。
在我们使用的线程库中,调度往往需要考虑下面的方式
时间片,每个线程CPU运行一段时间后,主动让出CPU
阻塞或休眠, 比如sleep, 等待锁,系统调用等操作本身会让CPU出现一定程度上的上下文切换
线程结束
主动放弃CPU, 在我们的环境中是sched_yield, 可以主动让出CPU。
在我们现在64位机器上使用的都是基于nptl线程库,相比32位中2.4内核下的linuxthread本身有很的大的提高。基本的切换上相差了近1倍。
虽然操作系统中已经考虑了不少调度的问题,但是这些是实际中的表现往往不尽人意
时间片不可控,一些CPU消耗性程序其实可以多运行一部分时间
上下文切换有一定的内核态用户态的切换。
大量的锁应用, 对性能会带来一定的影响
当存在大量长时间堵塞的时候, 需要大量的线程支持, 会对系统产生负面影响
这样的基础上,我们考虑采用一些其他方式来解决这些问题, 比如异步编程。
[百度分享]用户态线程库(1)
内核线程、轻量级进程、用户线程和LinuxThreads库
用户方式中线程的同步
linux线程库
百度知道”互帮互助分享知识
进程与线程的区别1
微软为百度用户提供英文搜索服务 年内上线
Windows核心编程(第五版)笔记 第八章 用户模式下的线程同步(Thread Sync...
分享:进来偷几句去做个性签名吧 1 百度空间_应用平台
Java面试题--设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1
爱国者发布百看电子书 支持用户直接访问百度内容 - 原创 - DoNews.com-IT社...
分享如何让百度快速收录你的博文。
分享:治疗颈椎腰椎秘方 百度空间_应用平台
分享:偏方治大病 百度空间_应用平台
分享:【宗教】中国古塔组图欣赏 百度空间_应用平台
利用百度知道推广网站的实战经验分享
百度空间里如何使用代码【漂亮边框欢迎分享】
分享:我是如何从百度来30万IP的
网站用户体验的76个体验点(豆丁、百度文库都要钱的,真是体验不好)
中国百度视频影视库戏曲在线欣赏1
动画版十万个为什么 - 视频短片 - 99盘官方论坛 用户交流-网盘资源分享
红色娘子军----美 - 美图频道 - 99盘官方论坛 用户交流-网盘资源分享
c#线程相关概念
C#教程:线程同步