多线程:常见题目


1、线程基本概念、线程状态

        线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。
        线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源( 线程ID、一组寄存器值、栈、调度优先级和策略、信号屏蔽字、errno变量、线程私有数据);
       它可与同属一个进程的其它线程共享进程所拥有的全部资源( 可执行文本程序、程序全局内存和堆内存、栈以及文件描述符)。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。 线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
     线程是程序中一个单一的顺序控制流程, 线程是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为 多线程

2、线程和进程的区别联系

1)基本单位:进程是拥有资源的基本单位,线程是调度和分派的基本单位。

        线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源(线程ID、一组寄存器值、栈、调度优先级和策略、信号屏蔽字、errno变量、线程私有数据)。它可与同属一个进程的其它线程共享进程所拥有的全部资源(可执行文本程序、程序全局内存和堆内存、栈以及文件描述符)。

2)从属关系:线程是进程的一部分,线程有时会被称为轻量级进程或轻权进程;一个线程只能属于某一个进程,一个进程可以有多个线程(至少有一个线程)。

3)系统开销:进程有进程控制块PCB,线程有线程控制块TCB,但线程控制块比进程控制块小得多。在创建或撤销进程的时候,由于系统都要为之分配和回收资源,导致系统的明显大于创建或撤销线程时的开销。

4)并发度:线程的划分尺度小于进程,使得多线程程序的并发性高。 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大的提高了程序运行效率。

5)资源管理方式:进程和线程的主要差别在于它们是不同的操作系统资源管理方式。系统在运行的时候会为每个进程分配不同的内存区域,但是不会为线程分配内存(线程所使用的资源是它所属的进程的资源),线程组只能共享资源。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。而一个线程的数据可以直接为其他线程所用,这不仅快捷,而且方便。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响;而线程只是一个进程中的不同执行路径,一个线程终止,整个进程就会终止。


3、线程的优点和缺点

优点:

1)线程可以有效地提高程序的并行性。有时候让程序同时执行多个任务是有用的。经典的例子是编辑文档时,还有实时统计文档中单词的个数;在网络编程的高性能服务器端,可以通过主线程来监听描述符是否有事件发生,有的话就将该事件通知工作进程处理(完成数据读写、接受新连接,处理客户请求),这就是Reactor模式,可以有效提高并行性。

2)有利于发挥多处理器的能力,使得程序效率极大提高。

2)和进程创建相比,线程创建的开销小很多,那么当需要创建的个数较多时,线程优势很明显;而且由于同样原因,线程之间切换开销小。

缺点:

1)由于一个进程的多个线程之间共享资源,这也带来了复杂的同步互斥问题,否则当多个线程共享相同内存时,无法确保每个线程看到一致的数据视图。

2)同步互斥、死锁以及锁的粒度都是编程需要考虑的问题。多线程程序调试比单线程调试困难,因为线程之间交互非常难以控制。


4、多线程同步和互斥有几种实现方法

1)互斥量

确保同一时间只有一个线程访问数据。互斥量(mutex)本质上是一把锁,访问共享资源前要对互斥量加锁,访问完后要释放锁。

2)读写锁(共享-独占锁)

        和互斥量类似,不过读写锁允许更高的并行性。互斥量要么是锁住状态要么是不加锁状态,而且一次仅允许一个线程对互斥量加锁。

        读写锁有三种状态:a. 读模式下加锁状态(所有试图以读模式对其进行加锁的线程都可以获得访问权,但如果试图以写模式加锁,必须阻塞直到所有线程释放读锁);b. 写模式下加锁状态(在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞);c. 不加锁状态。

3)条件变量

条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定条件发送。条件变量本身是由互斥量保护的。线程在改变条件状态前必须首先锁住互斥量,必须锁住互斥量以后才能计算条件。如果在规定的时间内条件满足就通知线程,否则生成一个代表出错码的返回变量。

4)信号量

如同进程一样,线程也可以通过信号量来实现通信,虽然是轻量级的。信号量函数的名字都以"sem_"打头。线程使用的基本信号量函数有四个。

  1. 信号量初始化。
    int sem_init (sem_t *sem , int pshared, unsigned int value);
    这是对由sem指定的信号量进行初始化,设置好它的共享选项(linux 只支持为0,即表示它是当前进程的局部信号量),然后给它一个初始值VALUE。
  2. 等待信号量。给信号量减1,然后等待直到信号量的值大于0。
    int sem_wait(sem_t *sem);
  3. 释放信号量。信号量值加1。并通知其他等待线程。
    int sem_post(sem_t *sem);
  4. 销毁信号量。我们用完信号量后都它进行清理。归还占有的一切资源。
    int sem_destroy(sem_t *sem);

5、多线程同步和互斥区别

    线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。

    线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。线程互斥可以看成是一种特殊的线程同步。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值