《多核与GPU编程:工具、方法及实践》----第3章 共享内存编程:线程 3.1 引言

简介: 本章目标: 学习线程的定义以及创建方法。 学习完成特定任务的初始化线程方法。 学习多种终止多线程程序的技术。 理解多线程访问共享数据过程中的主要问题,例如竞争和死锁。

本节书摘来自华章出版社《多核与GPU编程:工具、方法及实践》一书中的第3章,第3.1节, 作 者 Multicore and GPU Programming: An Integrated Approach[阿联酋]杰拉西莫斯·巴拉斯(Gerassimos Barlas) 著,张云泉 贾海鹏 李士刚 袁良 等译, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

第3章

共享内存编程:线程

本章目标:

学习线程的定义以及创建方法。

学习完成特定任务的初始化线程方法。

学习多种终止多线程程序的技术。

理解多线程访问共享数据过程中的主要问题,例如竞争和死锁。

学习信号量和监视器的定义和使用方法。

熟悉经典同步问题及其解决方法。

学习运行时动态管理线程。

学习多线程程序的调试技术。

3.1 引言

从20世纪60年代麻省理工学院引入兼容分时系统(CTSS)以来,多个程序并发执行的现象已经变得较为常见。操作系统通过中断当前正在执行的程序并将CPU的控制权交由另一个程序来完成这一功能。这种能有效地在多个程序间共享CPU时间(也即分时)的切换可以通过以下条件触发:

时钟或定时器的定期硬件中断

不定期硬件中断,例如某些设备的请求

调用操作系统功能,例如执行输入/输出(I/O)操作

每个运行中的程序组成一个进程,亦即为了管理程序,一个包括代码、数据、资源和执行状态信息的操作系统实体。

因此,每个进程值能在一个“时间片”内获得CPU的控制权,然后将控制权交回操作系统,操作系统再将CPU交于另一个进程,以此类推。单CPU上的分时如图3-1a所示。

分时这种方式可以提高计算资源的使用效率,但是它不能提高单个进程的运行速度,并且分时可能会由于减少分配给某个进程的时间片而直接降低程序性能,或者由于频繁调用操作系统的任务调度程序的开销而间接降低程序性能。

为了使程序获得更多的计算时间(利用调度制导语句改变程序优先级),必须将其划分为多个进程,在多核系统上也必须采取同样的方法才能提高性能,此类示例如图3-1b所示。最原始的生成(creating或者spawning)方法是调用fork函数,代码清单3-1给出了一个示例。


0ba958950257941fc4c961d90bb4a58b66bf120a


e6487ef3eb8e4b7816f97801dc9ec3e95aaf2c74

生成一个进程需要精确复制当前进程的内存,包括所有代码和数据,如图3-2所示。在原始程序(父进程)和生成程序(子进程)间的唯一区别是子进程继续执行fork语句的后的部分,亦即子进程没有收到返回值,因此子进程中的ChildID为0(见代码清单3-1第13行)。逻辑上看,就像一个新的进程开始在此处执行,从而使得两个进程执行不同任务(使两个进程执行同样的任务是无意义的)。

这种进程生成机制中一些显而易见的问题包括:

为什么复制代码?它不应该在内存不可变区吗?

子进程有父进程的所有数据的副本,那么如何在两个进程间交换信息?

由于有些程序在运行时改变代码,因此需要复制代码。这也是病毒中的常见特征,但这并不是一个正常的程序行为。对于后一个问题,系统已经提供了多种解决该问题 的机制,但是最为简单的还是访问一组共享变量。


4874395d58b7e2f137fe475365db7073da16acae

由于fork函数中保留和复制程序映像的开销,因此这种方法较为低效。幸运的是,还存在另一种通过线程来实现并发的方法,这将在下面进行介绍。

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
12天前
|
缓存 安全 Java
Java并发编程进阶:深入理解Java内存模型
Java并发编程进阶:深入理解Java内存模型
26 0
|
1月前
|
存储 SQL 缓存
揭秘Java并发核心:深度剖析Java内存模型(JMM)与Volatile关键字的魔法底层,让你的多线程应用无懈可击
【8月更文挑战第4天】Java内存模型(JMM)是Java并发的核心,定义了多线程环境中变量的访问规则,确保原子性、可见性和有序性。JMM区分了主内存与工作内存,以提高性能但可能引入可见性问题。Volatile关键字确保变量的可见性和有序性,其作用于读写操作中插入内存屏障,避免缓存一致性问题。例如,在DCL单例模式中使用Volatile确保实例化过程的可见性。Volatile依赖内存屏障和缓存一致性协议,但不保证原子性,需与其他同步机制配合使用以构建安全的并发程序。
55 0
|
4天前
|
缓存 Linux C语言
C语言 多进程编程(六)共享内存
本文介绍了Linux系统下的多进程通信机制——共享内存的使用方法。首先详细讲解了如何通过`shmget()`函数创建共享内存,并提供了示例代码。接着介绍了如何利用`shmctl()`函数删除共享内存。随后,文章解释了共享内存映射的概念及其实现方法,包括使用`shmat()`函数进行映射以及使用`shmdt()`函数解除映射,并给出了相应的示例代码。最后,展示了如何在共享内存中读写数据的具体操作流程。
|
15天前
|
安全 异构计算
为大型语言模型 (LLM) 提供服务需要多少 GPU 内存?
为大型语言模型 (LLM) 提供服务需要多少 GPU 内存?
40 0
为大型语言模型 (LLM) 提供服务需要多少 GPU 内存?
|
12天前
|
存储 机器学习/深度学习 PyTorch
深入理解GPU内存分配:机器学习工程师的实用指南与实验
给定一个模型架构、数据类型、输入形状和优化器,你能否计算出前向传播和反向传播所需的GPU内存量?
19 0
|
2月前
|
Java
JVM内存问题之jstack命令查看JVM线程快照如何解决
JVM内存问题之jstack命令查看JVM线程快照如何解决
|
24天前
|
存储 NoSQL Java
Tair的发展问题之Tair对于不同存储介质(如内存和磁盘)的线程分配是如何处理的
Tair的发展问题之Tair对于不同存储介质(如内存和磁盘)的线程分配是如何处理的
|
2月前
|
存储 安全 Java
Java面试题:请解释Java内存模型(JMM)是什么,它如何保证线程安全?
Java面试题:请解释Java内存模型(JMM)是什么,它如何保证线程安全?
81 13
|
2月前
|
微服务
多线程内存模型问题之在单例模式中,volatile关键字的作用是什么
多线程内存模型问题之在单例模式中,volatile关键字的作用是什么
|
2月前
|
缓存 Java 编译器
多线程内存模型问题之保证Java中的原子性,如何解决
多线程内存模型问题之保证Java中的原子性,如何解决

热门文章

最新文章