C++多线程编程一
1.C++多线程初步:
#include <iostream>
#include <thread>
#include <Windows.h> using namespace std; void run()
{
MessageBoxA(, "hello world", "hello china", ); } void main0101()
{
//同步(阻塞)
run();
run();
run(); cin.get();
} void main0102()
{
//并行,异步,非阻塞
thread t1(run); //根据函数初始化并执行,t1在栈上
thread t2(run);
thread t3(run);
thread t4(run); cin.get();
} void main0103()
{
//并行,异步,非阻塞
//thread t[5]{ run,run,run,run,run }; //error C2440: “初始化”: 无法从“void (__cdecl *)(void)”转换为“std::thread”
thread t[]{ thread(run),thread(run), thread(run), thread(run), thread(run) }; //初始化线程数组(线程池) cin.get();
} void main0104()
{
//堆上
thread *pthread1(new thread(run));
thread *pthread2(new thread(run));
thread *pthread3(new thread(run)); cin.get();
} void main()
{
//堆上开辟了线程数组
thread *pthread1(new thread[]{ thread(run),thread(run), thread(run), thread(run), thread(run) }); cin.get();
}
2. 线程冻结与解冻调试:
#include <iostream>
#include <thread>
#include <Windows.h>
#include <cstdlib> using namespace std; void test()
{
int i = ;
while ()
{
cout << ++i << endl;
Sleep();
}
} void main()
{
thread *p(new thread(test)); //堆上 system("pause"); system("pause"); system("pause"); system("pause"); cin.get();
}
3. 多线程传参:
#include <iostream>
#include <thread>
#include <Windows.h> using namespace std; void showmsg(const char *str1, const char *str2)
{
MessageBoxA(, str1, str2, );
} void main()
{
thread th1(showmsg, "", "");
thread th2(showmsg, "", "");
thread th3(showmsg, "", "");
cin.get();
}
4. 多线程的join 和detach:
#include <iostream>
#include <thread>
#include <array>
#include <Windows.h> using namespace std; //join让当前主线程等待所有子线程执行完成才能退出
//detach脱离主线程的绑定,主线程退出的时候,不影响子线程。
void show()
{
MessageBoxA(, "", "", );
} void main0401()
{
array<thread, > threads{ thread(show),thread(show),thread(show) }; for (int i = ; i < ; i++)
{
cout << threads[i].joinable() << endl; //判断是否可以join
threads[i].join(); //主线程等待子线程执行完成再退出
} auto n = thread::hardware_concurrency(); //获取CPU是几核
cout << n << endl; cin.get();
} void main()
{
thread th(show);
//th.join();
th.detach(); //脱离主线程,主线程挂了不报错
//detach以后线程无法通信 th.joinable();
}
5. 原子变量与线程安全:
#include <iostream>
#include <thread>
#include <mutex> //互斥量
#include <atomic> //原子变量 using namespace std; //线程安全,多线程访问不冲突就是线程安全,冲突则不安全
//int num = 0; //mutex m; //互斥,加锁解锁浪费时间 atomic_int num(); //原子变量不会发生线程冲突,属于线程安全 void run()
{
for (int i = ; i < ; i++)
{
//m.lock();
num++;
//m.unlock();
}
} void main()
{
clock_t start = clock(); thread th1(run);
thread th2(run);
th1.join();
th2.join(); clock_t end = clock();
cout << num << endl;
cout << end - start << "ms" << endl; cin.get();
}
//全局变量,会发生冲突,结果不正确,速度快
//mutex,结果正确,速度慢
//atomic,结果正确,速度比mutex快
6. lambda 表达式与多线程:
#include <iostream>
#include <thread>
#include <Windows.h>
#include <chrono> using namespace std; void main0701()
{
//auto fun = []() {MessageBoxA(0, "1", "2", 0); };
//thread th1(fun);
//thread th2(fun); thread th1([]() {MessageBoxA(, "", "", ); });
thread th2([]() {MessageBoxA(, "", "", ); }); cin.get();
} void main()
{
//thread th1([]() {cout << this_thread::get_id() << endl; }); //获取当前线程的id
//thread th2([]() {cout << this_thread::get_id() << endl; }); thread th1([]() {
this_thread::sleep_for(chrono::seconds()); //等待3秒
this_thread::yield(); //让CPU先执行其他线程,空闲了再执行我
cout << this_thread::get_id() << endl; //获取当前线程的id
//this_thread::sleep_until(); //某个时刻到来之前一直等待
});
thread th2([]() {
this_thread::sleep_for(chrono::seconds()); //等待10秒
cout << this_thread::get_id() << endl;
}); cin.get();
}
7. 伪函数与多线程:
(1)伪函数概念:
#include <iostream>
using namespace std; struct func
{
void operator ()() //伪函数,可以将对象名当做函数名来使用
{
cout << "hello china hello cpp" << endl;
} void operator ()(int i) //伪函数,可以将对象名当做函数名来使用
{
cout << "hello china hello cpp! " << i << endl;
}
}; void main()
{
func f1;
f1(); func f2;
f2(); cin.get();
}
(2)伪函数与多线程:
#include <iostream>
#include <thread>
#include <Windows.h> using namespace std; struct MyStruct
{
MyStruct()
{
cout << "create" << endl;
}
~MyStruct()
{
cout << "end" << endl;
} void operator ()() //对象名当做函数名使用,重载了(),但()只适用于当前结构体对象
{
MessageBoxA(, "", "", ); }
}; void main()
{
MyStruct go1;
thread t1(go1); MyStruct go2;
thread t2(go2); //MyStruct()是构造函数,创建一个临时对象,匿名对象
//MyStruct()();
//thread t3(MyStruct());//匿名的对象,不适合作为多线程参数,销毁太快 //MyStruct *p = new MyStruct;
MyStruct *p = new MyStruct();//多一个()就是构造函数 cin.get();
}
8. 成员函数构建多线程:
#include <iostream>
#include <thread>
#include <Windows.h> using namespace std; struct fun
{
void run1()
{
MessageBoxA(, "", "ABCDE", );
cout << "hello china" << endl;
} void run2(const char *str)
{
MessageBoxA(, str, str, );
cout << "hello china" << endl;
}
}; void main()
{
//fun *p(nullptr);
//p->run1(); //空类指针可以引用没有调用内部变量的成员函数 fun fun1;
//&fun::run引用成员函数
thread th1(&fun::run1, fun1);
thread th2(&fun::run1, fun1); thread th3(&fun::run2, fun1,"run2-1");
thread th4(&fun::run2, fun1, "run2-2"); cin.get();
}
9. 多线程通信future:
#include <iostream>
#include <thread>
#include <future>
#include <string>
#include <cstdlib> using namespace std; void main0401()
{
string str1("");
string str2("");
string str3(str1 + str2); //C++风格的字符串
cout << str3 << endl; cin.get();
} promise<string>val; //全局通信变量 void main()
{
thread th1([]()
{
future<string> fu = val.get_future();//获取未来的状态
cout << "等待中..." << endl;
cout << fu.get() << endl;
}); thread th2([]()
{
system("pause");
val.set_value("I love CPP");
system("pause");
}); th1.join();
th2.join(); }
10. 基于继承的多线程:
#include <iostream>
#include <thread> using namespace std; class zhangthread :public thread //C++代码重用-->继承
{
public:
zhangthread() :thread() //子类调父类的构造函数
{ } template <typename T, typename...Args> //子类调父类的构造函数,可变参数的构造
zhangthread(T && func,Args &&...args):thread( forward<T>(func), forward<Args>(args)... )
{ } void run(const char *cmd) //新增的功能
{
system(cmd);
}
}; void main()
{
zhangthread t1([](){cout << "hello this is Zhang"<<endl;});
t1.run("calc"); zhangthread t2([](int num) {cout << "hello this is Zhang"<<num<<endl; }, );
t2.run("notepad"); cin.get();
}
11. 条件变量:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable> //条件变量 using namespace std; //线程通信,结合mutex
//一个线程,多个线程处于等待,通知一个或通知多个 mutex m; //线程互相排斥
condition_variable cv; //线程通信 void main()
{
thread **th = new thread * [];//开辟线程的指针数组 for (int i = ; i < ; i++)
{
th[i] = new thread([](int index)
{
unique_lock<mutex> lck(m); //锁定
cv.wait_for(lck, chrono::hours()); //一直等待
cout << index << endl; //打印编号
} , i ); //传递参数 this_thread::sleep_for(chrono::milliseconds()); //错开
} for (int i = ; i < ; i++)
{
lock_guard<mutex> lckg(m);//解锁向导
cv.notify_one(); //挨个通知
} for (int i = ; i < ; i++)
{
th[i]->join();
delete th[i];
} delete[]th; //释放指针数组 cin.get();
}
12. 获取线程的结果:
#include <iostream>
#include <thread>
#include <future>//线程将来结果
#include <chrono>//时间
#include <mutex> using namespace std; mutex g_m; void main()
{
auto run = [=](int index)->int
{
lock_guard<mutex> lckg(g_m); //加锁
cout << this_thread::get_id() << " " << index << endl; //获取线程id
this_thread::sleep_for(chrono::seconds()); //等待10秒
return index * ; //返回结果
}; packaged_task<int(int)> pt1(run);
packaged_task<int(int)> pt2(run); //创建两个任务包 thread t1([&]() {pt1(); });
thread t2([&]() {pt2(); }); //开启线程 cout << pt1.get_future().get() << endl;
cout << pt2.get_future().get() << endl; //获取结果 t1.join();
t2.join(); cin.get();
}
13. 可变参数实现多线程:
#include <iostream>
#include <cstdarg>
#include <thread> using namespace std; //可变参数
int go(const char *fmt, ...)
{
va_list ap; //第一个数据(指针)
va_start(ap, fmt); //开始 vprintf(fmt, ap); //调用 va_end(ap); //结束 return ;
} void main()
{
thread th(go, "%sABCD%d____%c____%x", "12345abc", , 'A', ); cin.get();
}
14. 多线程实现并行计算:
#include <iostream>
#include <thread>
#include <future>
#include <vector>
#include <cstdlib> using namespace std; #define COUNT 1000000 //线程函数:
int add(vector<int> *arr, int start, int count)
{
static mutex m; //静态局部变量,只会初始化一次
int sum();//保存结果 for (int i = ; i < count; i++)
{
sum += (*arr)[start + i];//实现累加
} { //此处仅仅是计算过程中的显示,更清楚查看
lock_guard<mutex> lckg(m);//加锁,不让其他线程干涉 cout << "thread" << this_thread::get_id() << ",count=" << count << ",sum=" << sum << endl;
} return sum;
} void main()
{
vector<int> data(COUNT); //数组,100万的大小
for (int i = ; i < COUNT; i++)
{
data[i] = i % ; //0-999
} vector< future<int> > result;//结果数组 int cpus = thread::hardware_concurrency();//CPU核心的个数 for (int i = ; i < cpus * ; i++)
{
//1000 10= 100 * 10
//1000 9 = 1000 - 111*8
int batch_each = COUNT / (cpus * ); if (i == (cpus * ) - )
{
batch_each = COUNT - COUNT / (cpus * )*i;//最后一个承担的多一点
} //不断压入结果
result.push_back(async(add, &data, i*batch_each, batch_each));//async直接返回结果 } //汇总
int lastresult();
for (int i = ; i < cpus * ; i++)
{
lastresult += result[i].get();//汇总结果,累加
}
cout << "lastresule=" << lastresult << endl; cin.get();
}
C++多线程编程一的更多相关文章
- C语言多线程编程一
		1. Windows下同时打开多个对话框: #include <Windows.h> #include <process.h> //创建线程 void runmsg(void ... 
- Task C# 多线程和异步模型 TPL模型  【C#】43. TPL基础——Task初步  22 C# 第十八章 TPL 并行编程  TPL 和传统 .NET 异步编程一   Task.Delay() 和 Thread.Sleep() 区别
		Task C# 多线程和异步模型 TPL模型 Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task ... 
- iOS多线程编程之NSThread的使用
		目录(?)[-] 简介 iOS有三种多线程编程的技术分别是 三种方式的有缺点介绍 NSThread的使用 NSThread 有两种直接创建方式 参数的意义 PS不显式创建线程的方法 下载图片的例子 ... 
- iOS多线程编程之NSThread的使用(转)
		本文由http://blog.csdn.net/totogo2010/原创 1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation ... 
- [转] iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用
		介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统.这建立在任务并行执行的线程池模式的基础上的.它首 ... 
- [转]  iOS多线程编程之NSOperation和NSOperationQueue的使用
		<iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是用定义好 ... 
- [转]iOS多线程编程之NSThread的使用
		1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue ... 
- iOS 多线程编程之Grand Central Dispatch(GCD)
		介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其它的对称多处理系统的系统.这建立在任务并行运行的线程池模式的基础上的. 它 ... 
- 深入浅出Cocoa多线程编程之 block 与 dispatch quene
		深入浅出 Cocoa 多线程编程之 block 与 dispatch quene 罗朝辉(http://www.cppblog.com/kesalin CC 许可,转载请注明出处 block 是 Ap ... 
随机推荐
- Kubernetes的UI界面Kubernetes Dashboard的搭建
			1.搭建准备 Kubernetes集群的安装部署 2.搭建过程 2.1.在master节点上创建kubernetes-dashboard.yaml cd /etc/kubernetes vim kub ... 
- SpringBoot中使用LoadTimeWeaving技术实现AOP功能
			目录 1. 关于LoadTimeWeaving 1.1 LTW与不同的切面织入时机 1.2 JDK实现LTW的原理 1.3 如何在Spring中实现LTW 2. Springboot中使用LTW实现A ... 
- Add Strings大整数加法十进制求和 & Add Binary二进制求和
			[抄题]: 以字符串的形式给出两个非负整数 num1 和 num2,返回 num1和 num2 的和. 比如一个50位+一个100位. 给定 num1 = "123",num2 = ... 
- jQuery绑定事件的四種方式
			这篇文章主要介绍的是jQuery绑定事件的四种方式相关内容,下面我们就与大家一起分享. jQuery绑定事件的四种方式 jQuery提供了多种绑定事件的方式,每种方式各有其特点,明白了它们之间的异同点 ... 
- BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)
			4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1930 Solved: 1231[Submit][Statu ... 
- 用word2016 写CSDN 博客
			目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写 ... 
- linux每天一小步---tail命令详解
			1 命令功能 tail命令用于显示文件中末尾的内容(默认显示最后10行内容) 2 命令语法 tail [选项参数] [文件名1] [文件名2] 3 命令参数 -f 用于循环读取文件的内容,监视文件的 ... 
- ISO in CSS content
			Name Numeric Description Hex ISO in CSS content Octal no-break space %A0 p:before { content: ... 
- excel中如何让每n行显示同一个数据
			由于需要将数据按照下表格式存储,以方便读取展示,年份列需要每隔7行再递增1 方法: 1. 输入这个公式: = INT((ROW(E1)-1)/ 5)+ 1 进入一个空白单元格,您可以在其中填写序列号, ... 
- [Java]java内存及数据区
			Java运行时的数据区包括:(其中前两个是线程共享的) 1.方法区(Method Area) 存储已被虚拟机加载的类信息.常量.静态变量.即时编译器编译后的代码等数据 2.堆(Heap) 存放对象实例 ... 
