C++11并发与多线程笔记(13)补充知识、线程池浅谈、数量谈、总结

C++11并发与多线程笔记(13)补充知识、线程池浅谈、数量谈、总结,第1张

C++11并发与多线程笔记(13)补充知识、线程池浅谈、数量谈、总结

文章目录
  • 1、补充知识
    • 1.1 虚假唤醒
    • 1.2 atomic
  • 2、浅谈线程池
    • 2.1 场景设想
    • 2.2 线程池
    • 2.3 实现方式
  • 3、谈线程池创建线程数量
    • 3.1 线程开的数量极限问题
    • 3.2 线程创建数量建议

1、补充知识 1.1 虚假唤醒
  • notify_one或者notify_all唤醒wait()后,实际有些线程可能不满足唤醒的条件,就会造成虚假唤醒,可以在wait中再次进行判断解决虚假唤醒。
  • 解决:wait中要有第二个参数(lambda),并且这个lambda中要正确判断所处理的公共数据是否存在。
1.2 atomic
atomic atm;
atm = 0;
void ThreadA()
{
    for (int i = 0; i < 1000000; i++)
    {
        atm += 1;		//原子操作
    }
    return;
}
void ThreadB()
{
	while (true)
    {
        cout << atm << endl;		//读atm是个原子操作,但是整个这行代码并不是一个原子操作
    }	//end while
}
  • 这里B线程中(第15行代码),只有读取atm是原子 *** 作,但是这一整行代码cout << atm << endl;并不是原子操作,这就会导致最终显示在屏幕上的值是一个“曾经值”。
atomic atm;
atm = 0;
auto atm2 = atm;	//这种定义时初始化 *** 作不允许
atomic atm3;
atm3 = atm;			//这种拷贝赋值运算符也不让用
  • 这里第三行代码,这种定义时初始化 *** 作不允许,显示“尝试引用已删除的函数”,说名编译器内部肯定把拷贝构造函数给干掉了。
  • 第5行代码,这种拷贝赋值运算符也不让用。
atomic atm;
atm = 0;
atomic atm2(atm.load());
auto atm3(atm.load());
  • 使用load()函数可以以原子方式读取atomic对象的值。
atomic atm;
atm = 0;
atomic atm2(atm.load());
atm2.store(12);
  • 使用store()函数可以以原子方式写入内容。

原子 *** 作实质上是:不允许在进行原子对象 *** 作时进行CPU的上下文切换

2、浅谈线程池 2.1 场景设想
  • 服务器程序,每来一个客户端,就创建一个新线程为这个客户提供服务。
  • 问题:
    • 2万个玩家,不可能给每个玩家创建一个新线程,此程序写法在这种场景下不通。
    • 程序稳定性问题:编写代码中,“时不时地突然”创建一个线程,这种写法,一般情况下不会出错,但是不稳定的;
2.2 线程池
  • 线程池:把一堆线程弄到一起,统一管理。这种统一管理调度,循环利用的方式,就叫做线程池。
2.3 实现方式
  • 程序启动时,一次性创建好一定数量的线程。这种方式让人更放心,觉得程序代码更稳定。
3、谈线程池创建线程数量 3.1 线程开的数量极限问题
  • 一般来讲,2000个线程基本就是极限;再创建就会崩溃。
3.2 线程创建数量建议
  • 当采用某些技术开发程序,一定要根据API接口提供商的建议,比如创建线程数量为CPU的线程数量,或者CPU线程数量乘2,再或者CPU线程数量乘2再加2,等等。一定要遵照专业建议和指示来,专业意见确保程序高效执行。
  • 创建多线程完成业务:考虑可能被阻塞的线程数量,创建多于最大被阻塞线程数量的线程,如100个线程被阻塞再充值业务,开110个线程就是很合适的。
  • 线程创建数量尽量不要超过500个,尽量控制在200个之内;

注:本人学习c++多线程视频地址:C++多线程学习地址

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5156371.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-18
下一篇 2022-11-18

发表评论

登录后才能评论

评论列表(0条)

保存