20191330雷清逸 学习笔记7

2021/10/31 23:17:04

本文主要是介绍20191330雷清逸 学习笔记7,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

20191330 雷清逸 学习笔记7(第四章)

一、知识点归纳以及自己最有收获的内容

知识点归纳

摘要

本章论述了并发编程,介绍了并行计算的概念,指出了并行计算的重要性;比较了顺序算法与并行算法,以及并行性与并发性;解释了线程的原理及其相对于进程的优势;通过示例介绍了 Pthread中的线程操作,包括线程管理函数,互斥量、连接、条件变量和屏障等线程同步工具;通过具体示例演示了如何使用线程进行并发编程,包括矩阵计算、快速排序和用并发线程求解线性方程组等方法;解释了死锁问题,并说明了如何防止并发程序中的死锁问题;讨论了信号量,并论证了它们相对于条件变量的优点;解释了支持Linux中线程的独特方式。编程项目是为了实现用户级线程。它提供了一个基础系统来帮助读者开始工作。这个基础系统支持并发任务的动态创建、执行和终止,相当于在某个进程的同一地址空间中执行线程。读者可通过该项目实现线程同步的线程连接、互斥量和信号量,并演示它们在并发程序中的用法,该编程项目会让读者更加深入地了解多任务处理、线程同步和并发编程的原理及方法。

最有收获的部分

  • 线程的优缺点
  • 线程操作
  • 线程管理函数
  • 线程同步
  • 死锁预防
  • 条件变量的使用

并行计算导论

  • 在早期,大多数计算机只有一个处理组件,称为处理器或中央处理器(CPU)。受这种硬件条件的限制,计算机程序通常是为串行计算编写的。
  • 近年来,随着多核处理器的出现,大多数操作系统(如Linux)都支持对称多处理(SMP)。甚至对于普通程序员来说,并行计算也已经成为现实。显然,计算的未来发展方向是并行计算。在本章中,我们将介绍通过并发编程实现并行计算的基本概念和方法。

线程

  • 原理:

    一个操作系统(OS)包含许多并发进程。在进程模式中,进程是独立的执行单元。所有进程均在内核模式或用户模式下执行。

  • 线程与进程的区别:

    线程是某进程同一地址空间上的独立执行单元。线程是住在进程房子里的人。房子里的每个人都可以独立做自己的事情,但是他们会共用一些公共设施。

  • 线程的优点:

    (1)线程创建和切换速度更快:进程的上下文复杂而庞大。其复杂性主要来自管理进程映像的需要。要想创建新的进程,操作系统必须为进程分配内存并构建页表。若要在某个进程中创建线程,操作系统不必为新的线程分配内存和创建页表,因为线程与进程共用同一个地址空间。

    (2)线程的响应速度更快:一个进程只有一个执行路径。当某个进程被挂起时,整个进程都将停止执行。相反,当某个线程被挂起时,同一进程中的其他线程可以继续执行。

    (3)线程更适合并行计算:并行计算的目标是使用多个执行路径更快地解决问题。在进程模型中,各进程不能有效共享数据,因为它们的地址空间都不一样。为了解决这个问题,进程必须使用进程间通信(IPC)来交换数据或使用其他方法将公用数据区包含到其地址空间中。相反,同一进程中的所有线程共享同一地址空间中的所有(全局)数据。因此,使用线程编写并行执行的程序比使用进程编写更简单、更自然。

  • 线程的缺点:

(1)由于地址空间共享,线程需要来自用户的明确同步。

(2)许多库函数可能对线程不安全,例如传统strtok()函数将一个字符串分成一连串令牌。

(3)在单CPU系统上,使用线程解决问题世界上要比使用顺序程序慢,这是由在运行时创建线程和切换上下文的系统开销造成的。

线程操作

  • 线程的执行轨迹与进程类似。

  • 线程可在内核模式或用户模式下执行。

线程管理函数

Pthread库提供了用于线程管理的以下API:

pthread_create() //创建一个新的进程,成功则返回0;失败则返回错误代码。
pthread_exit() //线程终止函数,0表示正常终止;非0表示异常终止。
pthread_cancel() //结束某个线程,只是请求取消运行。
pthread_equal() //比较线程ID,不同返回0;否则返回非0。
pthread_join() //等待另一个线程终止。

线程同步

由于线程在进程的同一地址空间中执行,它们共享同一地址空间中的所有全局变量和数据结构。当多个线程试图修改同一共享变量或数据结构时,如果修改结果取决于线程的执行顺序,则称之为竞态条件。在并发程序中,绝不能有竞态条件。否则,结果可能不一致。

  • 互斥量

    最简单的同步工具是锁,它允许执行实体仅在有锁的情况下才能继续执行。在Pthread中,锁被称为互斥量,意思是相互排斥。有两种方法可以初始化互斥量。

    (1)静态方法:pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER

    定义互斥量m,并使用默认属性对其进行初始化。

    (2)动态方法:pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t,*addr)

    通过attr参数设置互斥属性。

  • 死锁预防

互斥量使用封锁协议。如果某线程不能获取互斥量,就会被阻塞,等待互斥量解锁后再继续。

死锁是一种状态,在这种状态下,许多执行实体相互等待,因此都无法继续下去。

  • 条件变量

条件变量提供了一种线程协作的方法。

条件变量也可以通过两种方法进行初始化。

(1)静态方法:pthread_cond_t con = PTHREAD_COND_INITIALIZER

定义一个条件变量con,并使用默认属性对其进行初始化。

(2)动态方法:另一种是动态方法,使用pthread_cond_init()函数,可通过attr参数设置条件变量。



这篇关于20191330雷清逸 学习笔记7的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程