《多核与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盲盒。
相关文章
|
3天前
|
人工智能 文字识别 异构计算
NVIDIA-Ingest:英伟达开源智能文档提取及结构化工具,支持 GPU 加速和并行处理
NVIDIA-Ingest 是英伟达开源的智能文档提取工具,支持 PDF、Word、PPT 等多种格式,提供并行处理和 GPU 加速,适用于企业内容管理和生成式应用。
44 18
NVIDIA-Ingest:英伟达开源智能文档提取及结构化工具,支持 GPU 加速和并行处理
|
2月前
|
安全 程序员 API
|
2月前
|
监控 Java 数据库连接
线程池在高并发下如何防止内存泄漏?
线程池在高并发下如何防止内存泄漏?
118 6
|
2月前
|
存储 安全 UED
多线程在打包工具中的运用
【11月更文挑战第2天】本文介绍了多线程技术在打包工具中的应用,包括提高打包效率、优化用户体验和多线程安全考虑。通过并行处理文件和加速资源收集,多线程可以显著缩短打包时间。在用户体验方面,多线程使界面保持响应,并支持优先级处理。此外,文章还讨论了资源访问冲突和死锁预防的解决方案,确保多线程环境下的稳定性和安全性。
|
3月前
|
监控 Java 数据库连接
使用线程池时,如何避免内存泄漏的问题?
使用线程池时,如何避免内存泄漏的问题?
|
3月前
|
缓存 安全 Java
使用 Java 内存模型解决多线程中的数据竞争问题
【10月更文挑战第11天】在 Java 多线程编程中,数据竞争是一个常见问题。通过使用 `synchronized` 关键字、`volatile` 关键字、原子类、显式锁、避免共享可变数据、合理设计数据结构、遵循线程安全原则和使用线程池等方法,可以有效解决数据竞争问题,确保程序的正确性和稳定性。
68 2
|
4月前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
3月前
|
监控 数据可视化 Java
如何使用JDK自带的监控工具JConsole来监控线程池的内存使用情况?
如何使用JDK自带的监控工具JConsole来监控线程池的内存使用情况?
|
4月前
|
监控 Java 数据库连接
使用线程池时,如何避免内存泄漏的问题?
使用线程池时,如何避免内存泄漏的问题?
|
4月前
|
Arthas 监控 Java
监控线程池的内存使用情况以预防内存泄漏
监控线程池的内存使用情况以预防内存泄漏