当前位置: 首页 > news >正文

整本书测试与巩固_《C++并发编程实战》笔记

   为了方便自己以后巩固与复习, 故出20道选择和10道编程设计题目, 后面会给出参考答案

1. 多选题目(20道)

  1. 关于std::thread的构造和析构,哪些说法正确?
    A. std::thread对象析构前必须调用join()或detach()
    B. 对已调用detach()的线程,无法再调用join()
    C. 对一个未调用join()的std::thread对象析构会引发std::terminate
    D. join()后的线程可以通过std::move转移给其他std::thread对象

  2. 线程参数传递的陷阱可能包括哪些?
    A. 传递局部变量的指针,但线程运行时变量已被销毁
    B. 使用std::ref传递非const引用
    C. 传参时发生隐式类型转换(如const char*转std::string)
    D. 传递std::unique_ptr时未使用std::move

  3. 关于线程所有权转移,正确的是?
    A. std::thread对象只能通过std::move转移所有权
    B. std::thread t1(f); std::thread t2 = t1;是合法操作
    C. std::thread对象可作为函数返回值
    D. std::thread对象存入std::vector需要显式调用std::move

  4. 关于join()和detach(),错误的是?
    A. join()会阻塞当前线程直至目标线程结束
    B. detach()后的线程生命周期与std::thread对象无关
    C. 对已join()的线程再次调用join()会导致编译错误
    D. detach()的线程资源由C++运行时自动回收

  5. 如何正确使用RAII管理线程?
    A. thread_guard在析构时调用join()
    B. scoped_thread的构造函数必须检查线程是否可join
    C. RAII对象在异常发生时自动释放线程资源
    D. thread_guard禁止拷贝构造和赋值操作

  6. 下面代码可能的问题是什么?

    void f(int& x) { x++; }
    int main() {
        int a = 0;
        std::thread t(f, a);
        t.join();
    }
    
    

    A. 参数a未使用std::ref传递
    B. x++未加锁,导致数据竞争
    C. 线程t的参数会拷贝到新线程栈
    D. a的修改对主线程不可见

  7. 关于硬件并发的正确描述是?
    A. std::thread::hardware_concurrency()返回的是物理CPU核心数
    B. 硬件并发数一定等于可并行执行的最大线程数
    C. 任务切换可以实现与硬件并发相同的性能
    D. 多核系统中,硬件并发数可能大于1

  8. 以下哪些操作会抛出std::system_error?
    A. 对未关联线程的std::thread对象调用join()
    B. 对已detach()的std::thread对象调用detach()
    C. 对joinable()为false的线程调用join()
    D. 构造std::thread时参数类型不匹配

  9. 关于std::async,正确的是?
    A. 默认策略下可能在新线程或当前线程执行任务
    B. std::launch::deferred表示延迟到get()调用时执行
    C. std::async的返回值可以忽略
    D. 必须通过std::future获取结果

  10. 以下场景可能引发数据竞争的是?
    A. 两个线程同时读取同一非原子变量
    B. 一个线程写,另一个线程读未同步的共享变量
    C. 使用std::mutex保护所有共享变量访问
    D. 原子变量的load()和store()无内存序约束

  11. 关于互斥量,错误的是?
    A. std::lock_guard在作用域结束时自动释放锁
    B. std::unique_lock支持手动加锁和解锁
    C. 递归互斥量允许同一线程重复加锁
    D. std::mutex的lock()和unlock()必须配对调用

  12. 条件变量的正确用法是?
    A. wait()必须在循环中检查条件
    B. notify_one()会唤醒所有等待线程
    C. std::condition_variable必须与std::mutex配合使用
    D. wait()会自动释放锁并阻塞线程

  13. 关于原子操作,正确的描述是?
    A. std::atomic::load()保证顺序一致性
    B. memory_order_relaxed不提供同步保证
    C. fetch_add()是原子的读-修改-写操作
    D. 原子操作能完全取代互斥量的使用

  14. 设计无锁数据结构的关键挑战是?
    A. 正确处理ABA问题
    B. 确保所有操作均为原子
    C. 避免死锁和优先级反转
    D. 依赖硬件支持的原子指令

  15. 关于内存模型,错误的是?
    A. C++内存模型定义了多线程下的操作可见性
    B. std::atomic默认使用memory_order_seq_cst
    C. 编译器可能对非原子操作进行指令重排
    D. memory_order_consume适用于依赖数据排序

  16. 线程池的优点是?
    A. 减少线程创建销毁的开销
    B. 自动负载均衡
    C. 避免线程数量超过硬件并发数
    D. 支持优先级调度

  17. 以下哪些是多线程调试的常用工具?
    A. Valgrind Helgrind
    B. ThreadSanitizer
    C. GDB的info threads命令
    D. 基于日志的追踪

  18. 哪些情况下推荐使用并发?
    A. 需要实时响应大量用户输入
    B. 计算密集型任务可利用多核CPU
    C. 单个任务的执行时间极短
    D. IO操作频繁导致等待时间过长

  19. 以下说法错误的是?
    A. 线程切换的开销通常小于进程切换
    B. 并发一定比串行的性能更好
    C. 数据并行适用于SIMD架构
    D. 无锁数据结构一定比基于锁的高效

  20. 关于C++17并行算法,正确的是?
    A. 使用std::execution::par指定并行策略
    B. 所有标准算法均有并行版本
    C. 并行算法要求输入范围支持随机访问
    D. 可以自动避免数据竞争

2. 设计题目(10道)

  1. 多生产者多消费者线程安全环形队列
    要求:
    实现基于无锁设计的环形缓冲区,支持多个生产者和消费者同时操作。使用CAS保证操作的原子性,处理ABA问题。缓冲区满时生产者阻塞,空时消费者阻塞,使用C++11原子变量和条件变量。

  2. 内存屏障控制的多核计数器
    要求:
    设计高性能原子计数器,支持fetch_add操作,要求严格顺序一致性。使用memory_order_seq_cst,对比改为memory_order_relaxed后的正确性差异。验证不同内存序下多线程操作的可见性。

  3. Promise/Future实现异步流水线
    要求:
    构建异步处理流水线:数据读取→预处理→加密→写入文件。每阶段用独立线程处理,阶段间用promise/future传递结果。处理异常传播,确保加密失败时整个流水线优雅终止。

  4. 可中断线程池实现
    要求:
    实现可响应外部中断的线程池,支持动态提交任务和立即取消未执行任务。使用std::jthread(或自定义中断点)停止运行中的任务。要求管理未完成任务队列的线程安全清理。

  5. CAS无锁栈的ABA问题解决方案
    要求:
    实现无锁栈结构,解决ABA问题。采用"带标记指针"或双重CAS策略,验证插入/删除操作的线程安全性。测试高并发场景下栈的正确性,比较与有锁版本的性能差异。

  6. 基于条件变量的工作窃取调度器
    要求:
    设计工作窃取(Work-Stealing)调度器:每个Worker线程维护双端队列,空闲线程窃取其他队列任务。使用std::mutex和条件变量同步任务获取,避免死锁,实现负载均衡。

  7. 并行快速排序优化
    要求:
    使用C++17并行算法执行策略实现快速排序。对比std::execution::par与手动线程池实现的性能差异。处理递归划分时的任务调度,确保小数组切换为串行排序。

  8. 细粒度锁的哈希表设计
    要求:
    构建线程安全哈希表,每个桶独立加锁,支持高并发插入/查找/删除。实现动态扩缩容机制,确保rehash时不阻塞全表。测试不同锁粒度(全局锁 vs 分段锁)下的吞吐量。

  9. 检测并修复死锁场景
    要求:
    编写一个必然发生死锁的代码片段(例如:多个线程按不同顺序请求互斥锁)。使用分层锁策略或std::lock/std::scoped_lock修复死锁。集成Valgrind或TSAN工具验证修复效果。

  10. 原子操作实现无锁内存池
    要求:
    实现基于原子操作的无锁内存池,支持多线程高效分配/释放固定大小内存块。使用链表管理空闲块,通过CAS更新头指针。验证内存分配的正确性,处理高并发下的性能瓶颈。

参考答案:

// 待完成

相关文章:

  • C# 使用Markdown2Pdf把md文件转换为pdf文件
  • Flutter网页交互增强插件pulse_core_web的使用
  • “全志V821:智能玩具的理想之选”——科技赋能,乐趣升级
  • JVM调优关注的核心指标?
  • 《CircleCI:CircleCI:解锁软件开发持续集成(CI)和持续部署(CD)高效密码》
  • c++学习系列----002.写文件
  • Java面试八股—Redis篇
  • 空洞卷积(膨胀卷积)(Dilated Convolution / Atrous Convolution)
  • 【Redis事务】redis中事务的使用
  • kafka rocketmq rabbitmq 都是怎么实现顺序消费的
  • UG的一些操作步骤(自用笔记1)
  • 初阶数据结构习题【12】(3顺序表和链表)——138.随机表的复制
  • 【论文阅读】Looking to Listen at the Cocktail Party:一种与说话人无关的语音分离视听模型
  • IP风险度自检,互联网的安全“指南针”
  • 「Unity3D」UGUI运行时设置元素的锚点Anchor,维持元素Rect的显示不变,即待在原处
  • go的gmp
  • 在rv1106上部署vue3
  • Python 中 lambda 表达式、推导式和其他函数用法对比
  • DML介绍
  • 智慧应急消防解决方案(35页PPT)(文末有下载方式)
  • web网站开发团队介绍/seo外包公司报价
  • 网站建设公司 专题制作/百度seo发帖推广
  • 专门做恐怖电影的网站/网络营销的认识与理解
  • 什么网站可以做旅行行程/安卓优化大师最新版
  • 吴江企业建设网站/今日军事新闻热点事件
  • 简易网站制作软件/站内关键词自然排名优化