欢迎来到冰点文库! | 帮助中心 分享价值,成长自我!
冰点文库
全部分类
  • 临时分类>
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • ImageVerifierCode 换一换
    首页 冰点文库 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    正文样章 模板.docx

    • 资源ID:1336054       资源大小:53.34KB        全文页数:15页
    • 资源格式: DOCX        下载积分:3金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要3金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    正文样章 模板.docx

    1、正文样章 模板第10章 线程控制线程技术早在20世纪60年代就被提出,20世纪80年代中期多线程被应用到操作系统中。目前,多线程技术已经被许多操作系统所支持,包括Windows NT/2000和Linux。Linux是一个多用户、多任务的操作系统。多用户是指多个用户可以在同一时间使用计算机系统;多任务是指Linux可以同时执行几个任务,它可以在还没有执行完一个任务时又执行另一项任务。在操作系统设计上,从进程(Process)演化出线程(Thread),最主要的目的就是更好地支持多处理器,并且减小(进程/线程)上下文切换的开销。线程是在共享内存空间中并发的多道执行路径,它们共享一个进程的资源。在

    2、两个普通进程(非线程)间进行切换时,内核准备从一个进程的上下文切换到另一个进程的上下文要有很大的花费,包括保存老进程CPU状态,并加载新进程的保存状态,用新进程的内存映像替换老进程的内存映像。10.1 Linux线程根据操作系统的定义,进程是系统资源管理的最小单位,线程是计算机中程序执行的最小单位,运行时占用的系统资源较少,一个进程可以拥有多个线程。本节介绍Linux线程的一些基本概念,包括线程和进程的关系、线程的分类等。10.1.1 线程和进程的关系线程和进程十分相似,不同的只是线程比进程小,每个线程所占用的CPU时间是由系统分配的,也可以认为线程是操作系统分配CPU时间的基本单位,进程可以

    3、同时使用多个CPU来执行各个线程,达到最大程度的并行,以提高效率。一个进程至少需要一个线程作为它的指令执行体。从用户的角度看多个线程是同时执行的,从操作系统的角度看各个线程是交替执行的。系统不停地在各个线程之间切换,每个线程只有在系统分配的时间内才能获得CPU的控制权。& 如果是在CPU多核的主机上,多个线程是可以同时运行的。Linux是支持多线程的,在一个进程内生成多个线程。一个进程可以拥有一个或多个线程。线程和进程二者之间的关系有以下几点:1)线程采用了多个线程可共享资源的设计思想。在多进程情况下,每个进程都有自己独立的地址空间,在多线程情况下,同一进程内的线程共享进程的地址空间。线程和进

    4、程的最大区别在于线程完全共享相同的地址空间,运行在同一地址上。2)由于进程地址空间独立而线程共享地址空间,所以从一个线程切换到另一线程所花费的代价比进程低。3)进程本身的信息在内存中占用的空间比线程大。因此,线程更能充分地利用内存。线程可以看作是在进程内部执行的指定序列。4)线程间的通信比进程间的通信更加方便和省时。进程间的数据空间相互独立,彼此通信要以专门的通信方式进行,通信时必须经过操作系统,而同一进程的多个线程共享数据空间,一个线程的数据可以直接提供给其他线程使用,不必进过操作系统。线程机制支持并发程序设计技术,在多处理器上能真正保证并行处理。而在Linux实现线程很特别,Linux把所

    5、有的线程都当作进程实现。Linux下线程看起来就像普通进程(只是该进程和其他进程共享资源,如地址空间)。上述机制与Microsoft windows或是Sun Solaris实现差异很大。这些系统提供专门支持线程机制(轻量级进程)。一个进程的组成实体可以分为两大部分:线程集和资源集。进程中的线程是动态的对象,代表了进程指令的执行过程。资源,包括地址空间、打开的文件、用户信息等等,由进程内的线程共享。线程有自己的私有数据:程序计数器,栈空间以及寄存器。但是由于各线程共享进程的地址空间,因此可能会导致竞争,因此对某一块有多个线程要访问的数据需要一些同步技术。系统支持POSIX多线程接口,称为pth

    6、read(Posix Thread)。编写Linux下的多线程应用程序需要使用头文件pthread.h,连接时需要使用库libpthread.a。10.1.2 线程分类线程是一些相关指令的离散序列,线程与其它指令序列的执行相互独立,每个程序至少包括一个线程,即主线程。主线程负责程序的初始化工作,并且执行初始指令。此后主线程会为执行各种不同的任务决定是分别创建其它线程还是由主线程独立承担。不管哪种情况,每个程序至少都包含一个线程,并且每个线程都会维护自己当前的机器状态。目前线程有用户线程和内核线程两种方法实现。1.内核线程 Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合

    7、理以及不合理的请求)。内核需要多个执行流并行,为了防止可能的阻塞,多线程化是必要的。内核线程就是内核的分身,一个分身可以处理一件特定事情。Linux内核使用内核线程来将内核分成几个功能模块,像kswapd、kflushd等,这在处理异步事件如异步IO时特别有用。内核线程的使用是廉价的,唯一使用的资源就是内核栈和上下文切换时保存寄存器的空间。支持多线程的内核叫做多线程内核(Multi-Threads kernel )。内核线程的调度由内核负责,一个内核线程处于阻塞状态时不影响其他的内核线程,因为其是调度的基本单位。这与用户线程是不一样的。内核线程(Thread)或叫守护进程(Daemon),在操

    8、作系统中占据相当大的比例,当Linux操作系统启动以后,尤其是X window也启动以后,你可以用”ps -ef”命令查看系统中的进程,这时会发现很多以”d”结尾的进程名,确切说名称显示里面加 的,这些进程就是内核线程。系统的启动是从硬件-内核-用户态进程的,pid的分配是一个往前的循环的过程,所以随系统启动的内核线程的pid往往很小。2. 用户线程用户线程在用户空间中实现,允许多线程的程序运行时不需要特定的内核支持,内核不需要直接对用户线程进程调度,内核的调度对象和传统进程一样,还是进程本身,内核并不知道用户线程的存在。由于Linux内核没有轻量级进程(线程)的概念,因此不能独立地对用户线程

    9、进行调度,而是由一个线程运行库来组织线程的调度,其主要工作在于在各个线程的栈之间调度。如果一个进程中的某一个线程调用了一个阻塞的系统调用,整个进程就会被调度程序切换为等待状态,其他线程得不到运行的机会。因此Linux使用了异步I/O机制。用户线程的优点如下: 某些线程操作的系统消耗大大减少。比如,对属于同一个进程的线程之间进行调度切换时,不需要调用系统调用,因此将减少额外的消耗,一个进程往往可以启动上千个线程。 用户线程的实现方式可以被定制或修改,以适应特殊应用的要求。它对于多媒体实时过程等尤其有用。另外,用户线程可以比内核线程实现方法默认情况支持更多的线程。10.2 创建线程线程的创建通过函

    10、数pthread_create()来完成,该函数的声明如下:#include int pthread_create(pthread_t *thread,pthread_attr_t *attr, void * (*start_routine)(void *),void *arg);函数各参数含义如下: thread:该参数是一个指向线程标识符的指针,当线程创建成功时,用来返回创建的线程ID。 attr:该参数用于指定线程的属性,NULL表示使用默认属性。 start_routine:该参数为一个函数指针,指向线程创建后要调用的函数。这个被线程调用的函数也称为线程函数。 arg:该参数指向传递给

    11、线程函数的参数。如果创建的thread不需要参数,则最后一个参数设置为空指针。& 线程创建成功时,pthread_create函数返回0,若不为0则说明创建线程失败。常见的错误代码为EAGAIN和EINVAL。pthread_create函数的第2个参数attr是一个指向pthread_attr_t结构体的指针,该结构体指明待创建线程的属性。在头文件pthread.h中还声明了其他一些有用的系统调用,如表10-1所示。表10-1 创建线程其他系统函数函数说明pthread_t pthread_self(void)获取本线程的线程IDint pthread_equal(pthread_t thr

    12、ead1,pthread_t thread2)判断两个线程ID是否指向同一线程int pthread_once(pthread_once_t *once_control, void(*init_routine)(void)用来保证init_routine线程函数在进程中仅执行一次。下面是线程创建的示例。【例10-1】 线程创建creat_thread.c。#include #include #include #include void thread (void) int i=0;for (i=0;i5;i+)printf(“This is a new threadn” pthread_self

    13、()if (i=1)pthresd_exit(0);sleep(1);int main(void)pthread_t thid;printf(main thread is %un,pthread_self();if (pthread_create(&thid,NULL,(void *)thread,NULL) != 0) printf( creat thread errorn); exit(1);sleep(1);exit(0);用GCC编译并运行程序结果如图10-1所示。图10-1 创建线程程序首先打印出主线程的ID,然后打印新创建的线程的ID。10.3 线程属性创建线程函数pthread_

    14、create()的第二个参数用来指定线程的属性。线程属性主要有绑定属性、分离属性、堆栈地址、堆栈大小、优先级等。其中系统默认的是非邦定、非分离、缺省1M的堆栈、与父进程同样级别的优先级。(1)绑定属性在Linux中,采用的是“一对一”的线程机制。也就是一个用户线程对应一个内核线程。绑定属性就是指一个用户线程固定地分配给一个内核线程,因为CPU时间片的调度是面向内核线程(轻量级进程)的,因此具有绑定属性的线程可以保证在需要的时候总有一个内核线程与之对应,而与之对应的非绑定属性就是指用户线程和内核线程的关系不是始终固定的,而是由系统来分配。(2)分离属性分离属性是决定线程以一个什么样的方式来终止自

    15、己。在非分离情况下,当一个线程结束时,它多占用的线程没有得到释放,也就是没有真正的终止,需要通过pthread_join来释放资源。而在分离属性情况下,一个线程结束时会立即释放它所占有的系统资源。但这里有一点要注意的是,如果设置一个线程分离属性,而这个线程又运行得非常快的话,那么它很可能在pthread_create函数返回之前就终止了线程函数的运行,它终止以后就很有可能将线程号和系统资源移交给其他的线程使用,这时调用pthread_create()的线程就得到错误的线程号。下面来看如何设置线程的属性。1. 设置/获取 detachstate 属性detachstate 属性表示新创建的线程与

    16、进程中其它线程是处于分离状态还是可连接状态。其合法值包括: PTHREAD_CREATE_DETACHED:此选项使得使用 attr 创建的所有线程处于分离状态。线程终止时,系统将自动回收与带有此状态的线程相关联的资源。调用使用此属性创建的 pthread_detach()或 pthread_join()函数将导致错误。 PTHREAD_CREATE_JOINABLE:此选项使得使用 attr 创建的所有线程处于可连接状态。线程终止时,不会回收与带有此状态的线程相关联的资源。要回收系统资源应用程序必须调用使用此属性创建的线程的 pthread_detach()或 pthread_join()函

    17、数。detachstate 的缺省值是 PTHREAD_CREATE_JOINABLE。设置线程的 detachstate 属性的函数声明如下:int pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate); /*用于设置已初始化属性对象 attr 中的 detachstate 属性*/获取线程detachstate属性的函数声明如下:int pthread_attr_getdetachstate (pthread_attr_t *attr, int *detachstate);/*获取detachstate 属性

    18、*/2. 设置/获取 guardsize 属性guardsize 属性允许应用程序指定使用此属性对象创建的线程的守护区大小。所指定的守护区大小的单位为字节。大多数系统将守护区大小向上舍入为系统可配置变量 PAGESIZE 的倍数。如果指定了零值,则不会创建守护区。为应用程序提供了 guardsize 属性的作用为:溢出保护可能会导致系统资源浪费。如果应用程序创建大量线程,并且已知这些线程永远不会溢出其栈,则可以关闭溢出保护区。通过关闭溢出保护区,可以节省系统资源。l 线程在栈上分配大型数据结构时,可能需要较大的溢出保护区来检测栈溢出。guardsize 的缺省值为 PAGESIZE 字节。PA

    19、GESIZE 的实际值与实现相关,并且不可以在所有实现上使用相同值。如果用户堆栈的存储不是由 pthread 库分配的,将忽略 guardsize 属性。应用程序负责防止堆栈溢出。设置线程的 guardsize属性的函数声明如下:int pthread_attr_setguardsize (pthread_attr_t *attr, size_t guardsize);/*用于设置已初始化属性对象 attr中的 guardsize属性值*/获取线程guardsize属性的函数声明如下:int pthread_attr_getguardsize (pthread_attr_t *attr, si

    20、ze_t*guardsize);/*获取guardsize属性*/3. 设置/获取schedparam 属性schedparam 属性的合法值因调度策略的不同而异。对于SCHED_FIFO 和 SCHED_RR 调度策略,只需要 schedparam属性的 sched_priority 成员。可以通过 sched_get_priority_max()和 sched_get_priority_min()获取 sched_priority 的合法值范围。其他调度策略的 schedparam的必要内容是不确定的。设置线程的 schedparam属性的函数声明如下:int pthread_attr_s

    21、etschedparam (pthread_attr_t *attr,struct sched_param schedparam);/*用于设置已初始化属性对象 attr 中的 schedparam 属性*/获取线程schedparam属性的函数声明如下:int pthread_attr_getschedparam (pthread_attr_t *attr,struct sched_param *schedparam);/*获取schedparam属性*/4. 设置/ 获取schedpolicy 属性schedpolicy 属性允许通过此属性对象创建的线程使用特定的调度策略,包括SCHED_

    22、OTHER(正常、非实时)、SCHED_RR(实时、轮转法)和SCHED_FIFO(实时、先入先出)等3种,缺省为SCHED_OTHER。设置线程的 schedpolicy属性的函数声明如下:int pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy) ;/*用于设置已初始化属性对象 attr 中的 schedpolicy 属性*/获取线程schedpolicy属性的函数声明如下:int pthread_attr_getschedpolicy (pthread_attr_t *attr, int *policy);/*获取

    23、schedpolicy 属性*/5. 设置/ 获取inheritsched 属性inheritsched 属性选用是从创建线程中继承还是从此属性对象中获得调度策略及关联属性。inheritsched 有两种值可供选择: PTHREAD_INHERIT_SCHED:此选项指定从创建线程中继承调度策略及关联属性。如果使用 attr 创建了线程,将忽略 attr 参数中的调度策略和关联属性。 PTHREAD_EXPLICIT_SCHED:此选项指定,从此属性对象中获得已创建线程的调度策略及关联属性。设置线程的 inheritsched属性的函数声明如下:int pthread_attr_setinh

    24、eritsched (pthread_attr_t *attr, int inherit) ;/*用于设置已初始化属性对象 attr 中的 inheritsched 属性*/获取线程inheritsched属性的函数声明如下:int pthread_attr_getinheritsched (pthread_attr_t *attr, int *inherit) /*获取inheritsched属性*/6. 设置/获取 scope 属性scope 属性用来设置创建线程的竞争范围,其合法值包括: PTHREAD_SCOPE_SYSTEM:使用此竞争范围创建的线程,将与系统中(以及同一调度域中)的

    25、其他线程竞争资源。此属性一般用于表示用户线程应该直接绑定到内核调度实体。 PTHREAD_SCOPE_PROCESS:使用此竞争范围创建的线程,将直接与其进程内使用此调度竞争范围创建的其他线程争用资源。此属性一般用于表示不应绑定用户线程(不绑定到任何特定的内核调度的实体)。设置线程的 scope属性的函数声明如下:int pthread_attr_setscope (pthread_attr_t *attr, int scope);/*用于设置已初始化属性对象 attr 中的 contentionscope 属性*/获取线程scope属性的函数声明如下:int pthread_attr_get

    26、scope (pthread_attr_t *attr,int *scope); /*获取scope属性*/7. 设置/获取 stackaddr属性此属性选项指定创建的线程将要使用的堆栈地址。应用程序全面负责这些堆栈的分配、管理和取消分配。存储分配的选项为 malloc(3C)、brk(2)和 mmap(2)函数。如果使用此选项,则只能使用此属性对象创建一个线程。如果创建了多个线程,它们将使用同一个堆栈。stackaddr 属性的缺省值为 NULL。如果线程用户堆栈的存储不是由库分配的(也就是说,stackaddr 属性不是 NULL),将忽略 guardsize 属性。设置线程的 stack

    27、addr属性的函数声明如下:int pthread_attr_setstackaddr (pthread_attr_t *attr,void *stackaddr);/*用于设置已初始化属性对象 attr 中的 stackaddr 属性*/获取线程stackaddr属性的函数声明如下:int pthread_attr_getstackaddr (pthread_attr_t *attr, void *stackaddr);/*获取stackaddr属性*/8. 设置/获取 stacksize属性stacksize 属性用来设置创建线程的用户堆栈大小。其合法值包括: PTHREAD_STACK_

    28、MIN:此选项指定,使用此属性对象创建的线程的用户堆栈大小将使用缺省堆栈大小。此值为某个线程所需的最小堆栈大小(以字节为单位)。 对于 所 有 线 程 来 说 ,这个最小值可能无法接受。 stacksize:具体的大小。定义使用此属性对象创建的线程的用户堆栈大小(以字节为单位)。 此值必须大于或等于最小堆栈大小 PTHREAD_STACK_MIN。设置线程的 stacksize属性的函数声明如下:int pthread_attr_setstacksize (pthread_attr_t *attr,size_t stacksize);/*用于设置已初始化属性对象 attr 中的 stacksi

    29、ze 属性*/获取线程stacksize属性的函数声明如下:int pthread_attr_getstacksize(pthread_attr_t *_attr,size_t*stacksize);/*获取stacksize属性*/9. 设置/获取 guardsize属性guardsize 属性用来警戒堆栈的大小。设置线程的 guardsize属性的函数声明如下:int pthread_attr_setguardsize(pthread_attr_t *attr,size_t guardsize);/*用于设置已初始化属性对象 attr 中的 guardsize 属性*/获取线程guards

    30、ize属性的函数声明如下:int pthread_attr_getguardsize(pthread_attr_t *_attr,size_t*guardsize);/*获取guardsize属性*/【例10-2】 读取及设置线程属性。#include #include #include #include void *thread_function(void *arg);char message = Thread processing!;int thread_finished = 0;int main(int argc,char argv)int res;int state;pthread_t

    31、 a_thread;void *thread_result;pthread_attr_t thread_attr;res = pthread_attr_init(&thread_attr); if (res != 0)perror(It is failed!);exit(EXIT_FAILURE);if(res = pthread_attr_getdetachstate(&thread_attr,&state)= =-1)perror(pthread_attr_getdetachstate);exit(EXIT_FAILURE);elseprintf(The default detachstate is %dn,state);res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);if (res != 0)perror(Setting detached attribute failed);


    注意事项

    本文(正文样章 模板.docx)为本站会员主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2023 冰点文库 网站版权所有

    经营许可证编号:鄂ICP备19020893号-2


    收起
    展开