Windows 多线程编程入门(2)
简单总结下C++自带的 std::thread 缺点: joinable函数 t.joinable();
native_handle函数 yield函数 std::this_thread::yield();
hardware_concurrency 函数 条件变量 在经典的生产者消费者模式下,生产者和消费者就是通过condition variable来实现同步的。当有限的生产力无法满足日益增长的消费需求时,消费者进程就会去睡一觉,直到它想要的东西生产出来才醒来。 condition_variable需要和 unique_lock搭配使用。在一个线程调用wait之前,它必须持有unique_lock锁。当wait被调用时,该锁会被释放,线程会陷入沉睡,等待着 wait可以接受两个参数。此时第二个参数用于判断当前是否要沉睡。 []{ return msgQueue.size() > 0;});
while (msgQueue.size() <= 0) {
condvar.wait()
}
这里把沉睡的线程比作睡美人,万一王子变成了青蛙,来不及唤醒她,那睡美人不就得睡到天荒地老海枯石烂? 为了解决这个问题,通过wait_until和wait_for,你可以设定线程的等待时间。设置notify_all_at_thread_exit也许能帮得上忙。 atomic /*time:20180605 author:MISAYAONE */
#include<iostream>
#include<thread>
#include<Windows.h>
#include<mutex>
#include<condition_variable>
#include<queue>
using namespace std;
mutex mu_msg;
condition_variable cv_msg;
//消费者,生产者模式的简单实现(利用条件变量和互斥锁)
queue<int> msg_queue;
void producer(int start,int end)
{
for (int i=start;i<end;i++)
{
mu_msg.lock();
msg_queue.push(i);
mu_msg.unlock();
}
cout << "msg produced" << endl;
if (msg_queue.size() > 20)
{
cv_msg.notify_all();//沉睡在该变量上的所有线程都将被唤醒,并尝试获取互斥锁(只有一个消费者可获得互斥锁)
}
}
void consumer(int demand)
{
while (true)
{
unique_lock<std::mutex> ulock(mu_msg);
cv_msg.wait(ulock,[] {return msg_queue.size() > 0;});//尝试获取互斥锁,否则等待
printf("Consume msg %dn",msg_queue.front());
msg_queue.pop();
--demand;
if (!demand)
{
break;
}
}
}
mutex mu;//互斥锁对象
int num = 100;
void thread_func1()
{
for (int i=0;i<10;i++)
{
cout <<"thread 1's "<< i << endl;
Sleep(100);
}
while (num>0)//这里不能用while,好无知....
{
mu.lock();//互斥锁加锁
cout << "1还在执行" << num << endl;
num--;
mu.unlock();//互斥锁解锁
if (num < 50)
{
//当前线程就不再执行
this_thread::yield();
break;
}
}
}
void thread_func2(int n)
{
for (int i = 0; i<n; i++)
{
cout <<"thread 2's "<< i << endl;
Sleep(200);
}
while (num>0)
{
mu.lock();
cout <<"2还在执行"<< num << endl;
num--;
mu.unlock();
}
}
class A
{
public :
void thread_func3()
{
for (int i = 0; i<10; i++)
{
cout << "class A thread 3's " << i << endl;
Sleep(200);
}
}
};
class thread_guard
{
thread &t;
public:
explicit thread_guard(thread& _t):t(_t){}
~thread_guard()
{
if (t.joinable())
{
t.join();
}
}
//拷贝赋值默认去除
thread_guard(const thread_guard&) = delete;
thread_guard& operator=(const thread_guard&) = delete;
};
int main()
{
A a;
thread task00();//默认构造函数
thread task01(thread_func1);//正常构造函数
thread_guard g(task01);//出现异常后,函数退出,g局部对象对销毁,此时g调用析构函数,会自动执行task01的join函数,从而能够保证join一定会被调用
thread task02(thread_func2,10);//带args的线程构造函数
//thread task_i(move(task02));//转移线程所有权,此时再利用task02调用join和detach会报错
thread task03(&A::thread_func3,a);//传入类的成员函数作为线程构造函数的参数
if (task01.joinable())//此处不可以使用task00线程来判断
{
cout << "task01 is joinable" << endl;
}
//join函数顺序执行线程
task01.join();
task02.join();
//task_i.join();
//task03.join();
//不影响当前代码的执行,几个线程后台自行执行,不阻塞主线程
//task01.detach();
//task02.detach();
//task_i.detach();
task03.detach();
//lambda匿名函数
for (int j=0;j<20;j++)
{
thread t([j]() {cout << j << endl; });
t.detach();
}
for (int i = 0; i<10; i++)
{
cout << "main thread's " << i << endl;
Sleep(200);
}
cout << "task01.get_id() = " << task01.get_id() << endl;//获取线程ID
unsigned int core_num = std::thread::hardware_concurrency();
cout << "CPU 核数" << core_num << endl;
thread mutiple00(producer,10,20);
thread mutiple01(producer,20,30);
thread mutiple02(producer,30,40);
thread mutiple03(consumer,5);
thread mutiple04(consumer,8);
mutiple00.join();
mutiple01.join();
mutiple02.join();
mutiple03.join();
mutiple04.join();
cin.get();
return 0;
} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 基于Windows Server 2008 R2架设站点到站点的×××连接
- windows-phone-7 – 如何将SystemTray Progressbar绑定到选
- windows10更换mysql8.0.17
- 在Windows 10上安装PHP7和Apache2.4 – php7apache2_4.dll错
- .net – 禁用Windows Mobile 6.5中的菜单栏
- windows-server-2008-r2 – Windows服务的上次重启/启动时间
- 设置windows 10 wifi
- Windows下php+mysql5.7配置教程
- 窗口 – 保持自动控制的远程桌面会话“活着”
- 试图让异步在Windows C应用程序中工作
- 如何执行 Windows 恶意软件移除工具??
- 在Windows上,绑定装载卷在docker-compose中的行为
- 是否存在适用于Windows的seccomp模拟
- windows-server-2008 – Active Directory运行状
- audio – 在Windows Phone 8中以编程方式下载媒体
- windows – 找不到Sudo.尝试npm安装
- [Windows]关于 Windows 7 降级使用 Windows XP
- windows-server-2008 – Windows Server 2008 Sy
- Windows窗体项目中的WPF窗体
- 在DLL接口中使用boost :: shared ptr可以吗?