练习题与扩展阅读
练习题
基础题
- 进程和线程有什么区别?分别适合什么场景?
- 什么是上下文切换?为什么线程切换比进程切换快?
- 常见的进程间通信机制有哪些?各有什么优缺点?
- 死锁产生的四个必要条件是什么?如何预防死锁?
- 竞态条件是什么?如何避免竞态条件?
实操题
- 编写一个多线程程序,多个线程同时对一个全局变量做100万次加1操作,不加锁的情况下看结果是否正确,加锁后再看结果。
- 分别用管道、消息队列、共享内存实现两个进程之间的数据传输,对比性能差异。
- 编写一个死锁程序,然后用调试工具定位死锁,分析死锁产生的原因。
- 实现一个生产者消费者模型,用互斥锁和条件变量实现,多个生产者线程往队列里放数据,多个消费者线程从队列取数据。
思考题
- 为什么现在很多高并发框架都使用协程?协程相比线程有什么优势?
- 互斥锁和自旋锁各有什么优缺点?什么时候应该用自旋锁?
- 进程的上下文切换和线程的上下文切换分别需要保存哪些内容?为什么上下文切换会有开销?
- 很多语言推荐“不要通过共享内存来通信,要通过通信来共享内存“,你怎么理解这句话?这种方式有什么好处?
扩展阅读
书籍推荐
-
《操作系统导论》
- 第二部分虚拟化部分详细讲解了进程、线程、并发、锁等内容,通俗易懂,非常适合入门学习操作系统的并发机制。
-
《并发编程实战》(Java并发编程实战)
- Java并发编程的经典著作,深入讲解了Java并发编程的原理和最佳实践,适合Java开发者。
-
《Unix环境高级编程》
- 第10章信号、第15章进程间通信、第11章和第12章线程部分,详细讲解了Unix系统下的进程、线程和IPC机制。
-
《七周七并发模型》
- 介绍了七种不同的并发编程模型,包括线程与锁、函数式编程、Actor模型、CSP、数据并行、Lambda架构、流式计算,拓宽并发编程的视野。
在线资源
-
- IBM的文档,详细讲解了不同的线程实现模型。
-
- Linux内核官方文档,介绍CFS调度器的设计和实现原理。
-
- 深入讲解Go语言的goroutine调度器实现原理。
-
- 一系列关于并发编程的优质文章,深入讲解内存模型、锁、无锁编程等内容。
工具推荐
- ThreadSanitizer:Google开发的并发问题检测工具,可以检测竞态条件、死锁等问题,支持C/C++/Go/Java等语言。
- perf:Linux性能分析工具,可以分析上下文切换次数、锁竞争等性能问题。
- jstack/jconsole:Java的线程分析工具,可以查看线程状态,检测死锁。
- gdb/lldb:调试工具,可以查看线程调用栈,分析并发问题。
- go trace/pprof:Go语言的性能和并发分析工具。
参考答案
练习题的参考答案可以在附录/练习题参考答案.md中找到。建议先独立思考完成,再查看答案。