Linux多线程编程之基础篇

1.多线程基础

       Mutual exclusion lock(互斥锁) 用来锁定和解除锁定对共享数据访问的函数。


      Condition variable(条件变量) 用来阻塞线程直到状态发生变化的函数。


      Read-write lock读写锁-可用于对共享数据进行多次只读访问的函数,但是要修改共享数据则必须以独占方式访问。


      Counting semaphore(计数信号量)一种基于内存的同步机制。


      Parallelism(并行性) 如果至少有两个线程正在同时执行,则会出现此情况。


     Concurrency(并发性) 如果至少有两个线程正在进行,则会出现此情况。并发是一种更广义的并行性,其中可以包括分时这种形式的虚拟并行性。


2.结合线程和RPC(远程过程调用)


       通过将多个线程和一个远程过程调用(remote procedure call, RPC)结合起来,可以充分利用无共享内存的多处理器(如工作站集合)。这种结合将工作站集合视为一个多处理器,从而使应用程序的分布变得相对容易些。例如,一个线程可以创建多个子线程,每个子线程随后可以请求远程过程调用,从而调用另一个工作站上的过程。尽管初始线程此时仅创建了一些并行运行的线程,但是这种并行性会涉及到其他计算机。

     

3、用户级线程
      线程是多线程编程中的主编程接口。线程仅在进程内部是可见的,进程内部的线程会共享诸如地址空间、打开的文件等所有进程资源。

     用户级线程状态
    以下状态对于每个线程是唯一的。
    ■ 线程ID
    ■ 寄存器状态(包括PC和栈指针)
    ■ 栈
    ■ 信号掩码
    ■ 优先级
    ■ 线程专用存储


4、线程调度


       POSIX标准指定了三种调度策略:先入先出策略(SCHED_FIFO)、循环策略(SCHED_RR)和自定义策略(SCHED_OTHER)。SCHED_FIFO是基于队列的调度程序,对于每个优先级都会使用不同的队列。SCHED_RR与FIFO相似,不同的是前者的每个线程都有一个执行时间配额。


5、线程同步
      使用同步功能,可以控制程序流并访问共享数据,从而并发执行多个线程。共有四种同步模型:互斥锁、读写锁、条件变量和信号。
      ■ 互斥锁仅允许每次使用一个线程来执行特定的部分代码或者访问特定数据。
      ■ 读写锁允许对受保护的共享资源进行并发读取和独占写入。要修改资源,线程必须首先获取互斥写锁。只有释放所有的读锁之后,才允许使用互斥写锁。
      ■ 条件变量会一直阻塞线程,直到特定的条件为真。
      ■ 计数信号量通常用来协调对资源的访问。使用计数,可以限制访问某个信号的线程数量。达到指定的计数时,信号将阻塞。


6、关于栈
       通常,线程栈是从页边界开始的。任何指定的大小都被向上舍入到下一个页边界。不具备访问权限的页将被附加到栈的溢出端。大多数栈溢出都会导致将SIGSEGV信号发送到违例线程。将直接使用调用方分配的线程栈,而不进行修改。
       指定栈时,还应使用PTHREAD_CREATE_JOINABLE创建线程。在该线程的pthread_join(3C)调用返回之前,不会释放该栈。在该线程终止之前,不会释放该线程的栈。了解这类线程是否已终止的唯一可靠方式是使用pthread_join(3C)。为线程分配栈空间
       一般情况下,不需要为线程分配栈空间。系统会为每个线程的栈分配1MB(对于32位系统)或2MB(对于64位系统)的虚拟内存,而不保留任何交换空间。系统将使用mmap()的MAP_NORESERVE选项来进行分配。系统创建的每个线程栈都具有红色区域。系统通过将页附加到栈的溢出端来创建红色区域,从而捕获栈溢出。此类页无效,而且会导致内存(访问时)故障。红色区域将被附加到所有自动分配的栈,无论大小是由应用程序指定,还是使用缺省大小。


      注–对于库调用和动态链接,运行时栈要求有所变化。应绝对确定,指定的栈满足库调用和
动态链接的运行时要求。
       极少数情况下需要指定栈和/或栈大小。甚至专家也很难了解是否指定了正确的大小。甚至符合ABI标准的程序也不能静态确定其栈大小。栈大小取决于执行中特定运行时环境的需要。
      生成自己的栈
       指定线程栈大小时,必须考虑被调用函数以及每个要调用的后续函数的分配需求。需要考虑的因素应包括调用序列需求、局部变量和信息结构。有时,您需要与缺省栈略有不同的栈。典型的情况是,线程需要的栈大小大于缺省栈大小。而不太典型的情况是,缺省大小太大。您可能正在使用不足的虚拟内存创建数千个线程,进而处理数千个缺省线程栈所需的数千兆字节的栈空间。对栈的最大大小的限制通常较为明显,但对其最小大小的限制如何呢?必须存在足够的栈空间来处理推入栈的所有栈帧,及其局部变量等。属性对象要获取对栈大小的绝对最小限制,请调用宏PTHREAD_STACK_MIN。PTHREAD_STACK_MIN宏将针
      对执行NULL过程的线程返回所需的栈空间量。有用的线程所需的栈大小大于最小栈大小,因此缩小栈大小时应非常谨慎。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值