C++ 练习-多线程

#if 0  //CreateThread代码示例
#include<iostream>
#include<windows.h>
using namespace std;
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter)
{
	char* str = (char*)lpThreadParameter;
	while (true)
	{
		cout << "线程处理函数中接收到的参数是:" << str << endl;
		cout << "子线程ID: " << GetCurrentThreadId() << endl;

		Sleep(1000);
	}

	return 0;
	
}
int main()
{
	DWORD threadId = 0;
	HANDLE hThread = CreateThread(
		NULL,     //设为NULL表示默认安全性
		0,        //如果设为0,那么默认将使用与调用该函数的线程相同的栈空间大小             
		ThreadFun,//线程处理函数,函数名就是函数指针
		"hello thread!",//向线程函数传入的参数
		0,              //0表示创建后马上运行
		&threadId);
	if (hThread == NULL){
		cout << "线程创建失败,ERROR CODE : " << GetLastError() << endl;
	}
	cout << "线程的句柄:" << hThread << endl;
	cout << "子线程的ID:" << threadId << endl;
	cout << "主线程的ID:" << GetCurrentThreadId() << endl;

	//关闭线程句柄,引用计数-1,并没有结束线程
	//CloseHandle(hThread);//表示以后不再引用句柄
	getchar();

	//挂起线程
	SuspendThread(hThread);
	getchar();

	//恢复执行线程
	ResumeThread(hThread);
	getchar();

	return 0;
}
#endif
#if 0//多线程间消息通讯
#include<iostream>
#include<windows.h>
#include<stdio.h>
//自定义消息必须自定义在用户消息以上的数值
#define MY_MSG WM_USER+1
bool flag = true;

DWORD WINAPI ThreadFun1(LPVOID  param)
{
	//接收第二个线程发来的消息
	MSG msg;
#if 0 //GetMessage 如果有消息继续,否则阻塞
	while (GetMessage(
		&msg,//接收消息的线程ID
		NULL,//取得消息的窗口的句柄,当为NULL时获取所属线程的消息
		0,   //指定被检索的最小消息值的整数
		0    //指定被检索的最大消息值的整数
		))
	{
		switch (msg.message){
		case MY_MSG:
			printf("收到消息:%d\n", (int)msg.wParam);
			break;
		//case WM_QUIT:
		//	printf("收到WM_QUIT消息,退出!\n");//因为WM_QUIT消息会让GetMessage返回false所以不会进人循环
		//	break;
		}
	}
	printf("收到WM_QUIT消息,退出!\n");
#endif 
#if 1 //PeekMessage的用法 不阻塞线程
	while (flag)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){//得到消息返回非零,否则返回0值
			switch (msg.message){
			case MY_MSG:
				printf("收到消息:%d\n", (int)msg.wParam);
				break;
			case WM_QUIT:
				printf("收到QUIT消息,退出!\n");
				flag = false;
				break;
			}
		}
	}

#endif

	
	return 0;

}

DWORD WINAPI ThreadFun2(LPVOID  param)
{
	//给第一个线程发送消息
	DWORD threadId = (DWORD)param;
	int N = 1;
	while (TRUE){
		if (N <= 3){
			PostThreadMessage(threadId, MY_MSG, (WPARAM)N++, NULL);
		}
		else{
			PostThreadMessage(threadId, WM_QUIT, NULL, NULL);
			break;
		}
		Sleep(1000);
	}
	return 0;
}
int  main()
{
	DWORD threadID = 0;
	HANDLE hthread1 = CreateThread(NULL, 0, ThreadFun1, NULL, 0, &threadID);
	HANDLE hthread2 = CreateThread(NULL, 0, ThreadFun2, (LPVOID)threadID, 0, NULL);

	HANDLE hArr[] = { hthread1, hthread2 };
	WaitForMultipleObjects(2, hArr, TRUE, INFINITE);

	//getchar();
	system("pause");

	return 0;
}
#endif 
#if 0//静态TLS(线程本地存储变量)
#include<iostream>
#include<Windows.h>
#include<stdio.h>
//声明为静态TLS(线程本地存储变量)
__declspec(thread) int N = 0;//每个线程中的值互不影响

DWORD WINAPI ThreadFun1(LPVOID param){
	char *name = reinterpret_cast<char *>(param);//()还不能少
	while (TRUE){
		printf("线程%s打印:%d\n", name, ++N);
		Sleep(1000);
	}
}
DWORD WINAPI ThreadFun2(LPVOID param){
	char *name = reinterpret_cast<char *>(param);//()还不能少
	while (TRUE){
		printf("\t\t\t线程%s打印:%d\n", name, ++(++N));
		Sleep(1000);
	}
}
void main(){
	HANDLE hThread1 = CreateThread(NULL, 0, ThreadFun1, "thread1", 0, NULL);
	HANDLE hThread2 = CreateThread(NULL, 0, ThreadFun2, "thread2", 0, NULL);

	HANDLE hArr[] = { hThread1, hThread2 };
	WaitForMultipleObjects(2, hArr, TRUE, INFINITE);

	system("pause");
}

#endif
#if 0//动态TLS(Thread Local Storage)
#include<iostream>
#include<stdio.h>
#include<Windows.h>

DWORD WINAPI ThreadFun1(LPVOID param);
DWORD WINAPI THreadFun2(LPVOID param);
//动态TLS的索引
DWORD tlsIndex = 0;

int main()
{
	tlsIndex = TlsAlloc();//返回索引
	if (tlsIndex == TLS_OUT_OF_INDEXES){
		printf("分配TLS索引失败!\n");
		return 0;
	}
	//在主线程中设置一个值
	TlsSetValue(tlsIndex, "main cpp");
	char *pName = (char*)TlsGetValue(tlsIndex);
	printf("主线程打印: %s\n", pName);

	HANDLE hThread1 = CreateThread(NULL, 0, ThreadFun1, "A", 0, NULL);
	HANDLE hThread2 = CreateThread(NULL, 0, THreadFun2, "B", 0, NULL);

	HANDLE hArr[] = { hThread1, hThread2 };
	WaitForMultipleObjects(2, hArr, TRUE, INFINITE);//等待两个线程执行完毕

	TlsFree(tlsIndex);
	system("pause");
	return  0;
}
DWORD WINAPI ThreadFun1(LPVOID param){
	TlsSetValue(tlsIndex, "hello");
	while (true)
	{
		char *p = (char*)TlsGetValue(tlsIndex);
		printf("线程A打印:%s\n", p);
		Sleep(1000);

	}
}
DWORD WINAPI THreadFun2(LPVOID param){
	TlsSetValue(tlsIndex, "world");
	while (true)
	{
		char *p = reinterpret_cast<char *>(TlsGetValue(tlsIndex));
		printf("\t\t\t线程B打印:%s\n", p);
		Sleep(1000);
	}
}

	
#endif

#if 0//利用事件Event实现买票程序
#include<iostream>
#include<Windows.h>
#include<stdio.h>
#include<process.h>//_beginthread

void __cdecl SellThread1(void* param);
void __cdecl SellThread2(void* param);
int tickets = 100;

//个INVALID_HANDLE_VALUE ( vs2008下为0xfffffffff ) 实际值等于-1
//INVALID_HANDLE_VALUE类似与指针里的NULL,如果将指针释放后,应该立即将指针赋为NULL,否则出现野指针;
//同理,句柄执行closehandle后,应该立即将句柄置为INVALID_HANDLE_VALUE,即让句柄失效。
HANDLE hEvent = INVALID_HANDLE_VALUE;
int main()
{
	//创建事件,此刻为有信号状态,自动重置信号状态,初始化为有信号状态,线程可以直接获取
	hEvent = CreateEvent(NULL, FALSE, TRUE, L"事件对象");
	Sleep(1000);
	//主线程休眠1秒后,将信号量置为无信号状态
	//ResetEvent(hEvent);

	printf("开始卖票了!\n");

	//创建两个售票线程
	uintptr_t t1 = _beginthread(SellThread1, 0, "售票窗口A");
	uintptr_t t2 = _beginthread(SellThread2, 0, "售票窗口B");

	//无限等待两个线程全部执行完毕
	HANDLE hArr[] = { (HANDLE)t1, (HANDLE)t2 };
	WaitForMultipleObjects(2, hArr, TRUE, INFINITE);

	printf("卖票结束!\n");

	system("pause");
	return 0;
}
void __cdecl SellThread1(void* param){
	char *name = reinterpret_cast<char*>(param);
	while (tickets > 0){
		//如果事件对象为信号状态(没有线程拥有它),则线程可以获取它后继续执行
		//自动重置的事件对象,调用了WaitForSingleObject函数之后,自动重置为无信号,
		//即其他线程不能再抢占了
		WaitForSingleObject(hEvent, INFINITE);
		if (tickets > 0){
			Sleep(10);
		}
		//让事件变成有信号状态,相当于解锁
		SetEvent(hEvent);
	}
}
void __cdecl SellThread2(void* param){
	char *name = reinterpret_cast<char*>(param);
	while (tickets > 0){
		WaitForSingleObject(hEvent, INFINITE);
		if (tickets > 0){
			Sleep(10);
			printf("%s卖出第%d张票!\n", name, tickets--);
		}
		SetEvent(hEvent);
	}
}
#endif

#if 0//利用事件对象实现一个程序只允许运行一个进程
#include<iostream>
#include<windows.h>
#include<stdio.h>

int main()
{
	HANDLE hEvent = CreateEvent(NULL, FALSE, TRUE, L"事件对象");
	if (GetLastError() == ERROR_ALREADY_EXISTS){
		printf("程序已经运行了,退出!\n");
		getchar();

		CloseHandle(hEvent);
		return 0;
	}
	printf("程序第一次运行!\n");
	getchar();
	return 0;
}

#endif

#if 0//利用semaphore实现程序只允许一个进程运行
#include<iostream>
#include<Windows.h>
#include<stdio.h>

int main()
{
	HANDLE hSemaphore = CreateSemaphore(NULL, 3, 3, L"停车位");
	if (GetLastError() == ERROR_ALREADY_EXISTS){
		printf("程序已经运行,请不要开启多个进程!\n");
		getchar();
		CloseHandle(hSemaphore);
		return 0;
	}
	printf("程序第一次运行!\n");
	getchar();
	CloseHandle(hSemaphore);
	return 0;
}
#endif
#if 0 //采用互斥体来实现单进程运行
#include<iostream>
#include<Windows.h>
#include<stdio.h>


int main()
{
	HANDLE hMutex = CreateMutex(NULL, FALSE, L"售票互斥体");
	if (GetLastError() == ERROR_ALREADY_EXISTS){
		printf("程序已经运行,退出\n");
		getchar();

		CloseHandle(hMutex);
		return 0;
	}
	printf("第一次运行程序!\n");
	getchar();
	return 0;
}
#endif
#if 0  //信号量控制停车场车位
#include<windows.h>
#include<stdio.h>
DWORD WINAPI ThreadFun(LPVOID param);
struct Car{
	char name[20];
	DWORD time;
};
HANDLE hSemphore = INVALID_HANDLE_VALUE;

int main()
{
	//初始化三个停车位资源
	hSemphore = CreateSemaphore(NULL, 3, 3, L"停车场");
	HANDLE hArr[5] = { INVALID_HANDLE_VALUE };
	for (int i = 0; i < 5; ++i){
		Car *pCar = new Car;
		sprintf_s(pCar->name, "车辆%c", 'A' + i);
		pCar->time = 3 + i * 3;

		//创建车辆线程
		hArr[i] = CreateThread(NULL, 0, ThreadFun, (LPVOID)pCar, 0, NULL);
	}
	//等待所有线程执行完毕
	WaitForMultipleObjects(5, hArr, true, INFINITE);
	return 0;
}

DWORD WINAPI ThreadFun(LPVOID param)
{
	//如果有剩余车位资源(有信号状态),就放行(往下执行)
	WaitForSingleObject(hSemphore, INFINITE);
	Car *pCar = reinterpret_cast<Car*>(param);
	printf("%s进入停车场,停车%d秒!\n", pCar->name, pCar->time);
	Sleep(pCar->time * 1000);
	printf("%s离开停车场!\n", pCar->name);

	//释放一个停车位(信号量+1)
	ReleaseSemaphore(hSemphore, 1, NULL);

	return 0;
}

#endif

#if 0//互斥体 售票
#include<iostream>
#include<process.h>
#include<stdio.h>
#include<windows.h>

void __cdecl SellThread1(void* param);
void __cdecl SellThread2(void* param);
int tickets = 100;
HANDLE hMutex = INVALID_HANDLE_VALUE;

int main()
{
	hMutex = CreateMutex(NULL, FALSE, L"售票互斥体");

	printf("开始卖票了!\n");

	uintptr_t t1 = _beginthread(SellThread1, 0, "售票窗口A");
	uintptr_t t2 = _beginthread(SellThread2, 0, "售票窗口B");

	HANDLE hArr[] = { (HANDLE)t1, (HANDLE)t2 };
	WaitForMultipleObjects(2, hArr, true, INFINITE);
	printf("卖票结束!\n");
	system("pause");
	return 0;

}
void __cdecl SellThread1(void* param){
	char *name = reinterpret_cast<char *>(param);
	while (tickets > 0){
		//如果这个互斥体为有信号状态(没有线程拥有它),则线程获取它后继续执行
		WaitForSingleObject(hMutex, INFINITE);
		if (tickets > 0){
			Sleep(10);
			//CPU恰好执行到这里,这个时候线程的时间片到了,并且此时还剩最后一张票
			printf("%s卖出第%d张票!\n", name, tickets--);
		}
		//释放对互斥体的拥有权 ,它变成有信号状态
		ReleaseMutex(hMutex);
	}
}
void __cdecl SellThread2(void* param){
	char *name = reinterpret_cast<char *>(param);
	while (tickets > 0){
		WaitForSingleObject(hMutex, INFINITE);
		if (tickets > 0){
			Sleep(10);
			printf("%s卖出第%d张票!\n", name, tickets--);
		}
		ReleaseMutex(hMutex);
	}
}


#endif

#if 0 //pv操作  生产者 消费者模式 P操作指:通过  V操作指:释放
#include<windows.h>
#include<queue>
#include<process.h>
using namespace std;

queue<int> store;
int StoreSize = 3;//仓库可以放3个货物

int ID = 1;//货物起始ID
//随机时间数组,模拟随机生产和消费的速度
int arr1[10] = { 2, 1, 3, 5, 9, 2, 5, 2, 3, 7 };

//需要两个Event来通知
HANDLE hEvent1 = INVALID_HANDLE_VALUE;//有货物时通知消费者去取货物
HANDLE hEvent2= INVALID_HANDLE_VALUE;//仓库有空时通知生产者开始生产
//生产者
void ProducerThread(LPVOID param);
//消费者
void ConsumerThread(LPVOID param);

int main()
{
	//需要先开始生产
	hEvent1 = CreateEvent(NULL, TRUE, TRUE, L"事件对象1");
	//一开始,仓库没货取
	hEvent2 = CreateEvent(NULL, TRUE, FALSE, L"事件对象2");
	uintptr_t t1 = _beginthread(ProducerThread, 0, NULL);
	uintptr_t t2 = _beginthread(ConsumerThread, 0, NULL);
	//无限等待两个线程运行结束
	HANDLE hArr[] = { (HANDLE)t1, (HANDLE)t2 };
	WaitForMultipleObjects(2, hArr, TRUE, INFINITE);

	CloseHandle(hEvent1);
	CloseHandle(hEvent2);

	system("pause");

	return 0;
}
//生产者
void ProducerThread(LPVOID param){
	while (true)
	{
		WaitForSingleObject(hEvent1, INFINITE);//看event是否允许生产
		if (store.size() < StoreSize)//仓库有空才生产
		{
			int id = ID++;
			printf("生产货物:%d\n", id);
			store.push(id);
			Sleep(arr1[id % 10] * 1000);
		}
		else{//仓库满了
			ResetEvent(hEvent1);//把事件设为无信号状态
			printf("仓库满了!\n");
		}
		//如果仓库有货可以通知消费者来取货物了
		if (store.size() > 0){
			SetEvent(hEvent2);//让消费者的事件对象有信号
		}

	}
}
//消费者
void ConsumerThread(LPVOID param){
	while (true)
	{
		//看event2是否允许取货物
		WaitForSingleObject(hEvent2, INFINITE);
		if (store.size() > 0){
			int id = store.front(); store.pop();//获取队列中的货物
			printf("\t\t\t取出货物:%d\n", id);
			Sleep(arr1[(id + 3) % 10] * 1000);
		}
		else{//仓库空了
			ResetEvent(hEvent2);//设为无信号,不能取货物了
			printf("\t\t\t仓库空了!\n");
		}
		if (store.size() < 3){
			SetEvent(hEvent1);//通知生产者继续生产
		}
	}
}

#endif


//-------------------- C++11 多线程 -------------------------
#if 0//原子操作  线程并发,非原子操作错误演示
#include<iostream>
#include<atomic>//原子操作头文件
#include<thread>

using namespace std;
enum {
	T=100000
};
//atomic<int> N = 0;
int N = 0;
void ThreadFun(){
	for (int i = 0; i < T/*2*T*/; ++i){
		++N;//线程并发导致叠加操作,不是原子操作,因此肯定少于2T
	}
}

int main(){
	thread t1(ThreadFun);
	thread t2(ThreadFun);

	t1.join();
	t2.join();

	cout << N << endl;
	system("pause");
}

#endif

#if 0//原子操作  
#include<iostream>
#include<atomic>//原子操作头文件
#include<thread>

using namespace std;
enum {
	T = 1000000
};
atomic<int> N = 0;//原子操作,避免多线程并发导致的叠加操作
//int N = 0;
void ThreadFun(){
	for (int i = 0; i < T/*2*T*/; ++i){
		++N;
	}
}

int main(){
	thread t1(ThreadFun);
	thread t2(ThreadFun);

	t1.join();
	t2.join();

	cout << N << endl;
	system("pause");
}

#endif
#if 0//原子操作,十人赛跑
#include<iostream>
#include<atomic>
#include<thread>
#include<vector>

using namespace std;
using namespace std::this_thread;
atomic<bool> ready = false;//是否枪响

atomic_flag win = ATOMIC_FLAG_INIT;//终点线
void Run(int id){
	//抢没响不能跑
	while (!ready)
	{
		yield();//让其他线程先执行
	}
	for (int i = 0; i < 100000000; ++i){}
	//如果没有设置过,返回false
	if (!win.test_and_set()){
		cout << id << " 号选手赢得第一名!" << endl;
	}

}
int main(int id){
	//十个选手赛跑
	vector<thread> vecPlayer;
	for (int i = 0; i < 10; ++i){
		vecPlayer.push_back(thread(Run, i));
	}
	cout << "十个选手已经准备好了!" << endl;
	//准备发命令
	//sleep_for(chrono::seconds(3));
	cout << "...3..." << endl;
	sleep_for(chrono::seconds(1));
	cout << "...2..." << endl;
	sleep_for(chrono::seconds(1));
	cout << "...1..." << endl;
	//可以跑了
	ready = true;

	//等待所有选手跑完
	for (thread &t : vecPlayer){
		t.join();
	}
	
	system("pause");
	return 0;
}
#endif

#if 0   //C++11 互斥锁-1

#include<iostream>
#include<mutex>
#include<thread>
#include<stdexcept>
using namespace std;
using  namespace  std::this_thread;
mutex  m;

void  ThreadFun()
{
	try
	{
		for (int i = 0; i < 10; ++i)
		{
			sleep_for(chrono::seconds(1));
			m.lock();
			//lock_guard<mutex>   lck(m);//哪怕发生异常也是可以安全解锁,因为lck会析构,然后解锁mutex

			if (i == 3)  throw   logic_error("发生异常了!");//发生异常后m无法解锁,线程无法结束,所以程序会锁死无法向下执行

			cout << "A打印" << i << endl;

			m.unlock();//抛出异常时,导致没有unlock,使得B无法获取mutex, 死锁

		}

	}
	catch (logic_error  & e)
	{
		cout << "错误:" << e.what() << endl;
		
	}

}

void  ThreadFun2()
{
	for (int i = 0; i < 10; ++i)
	{
		sleep_for(chrono::seconds(1));

		//lock_guard<mutex>   lck(m);

		m.lock(); 
		cout << "B打印" << i << endl;
		m.unlock(); 
	}
}


int  main()
{

	thread  t1(ThreadFun);
	thread  t2(ThreadFun2);

	t1.join();
	t2.join();


	return 0;
}

#endif


#if 0  //C++11 互斥锁-2

#include<iostream>
#include<mutex>
#include<thread>
#include<stdexcept>
using namespace std;
using  namespace  std::this_thread;
mutex  m;

void  ThreadFun()
{
	try
	{
		for (int i = 0; i < 10; ++i)
		{
			sleep_for(chrono::seconds(1));
			//m.lock();
			lock_guard<mutex>   lck(m);//哪怕发生异常也是可以安全解锁,因为lck会析构,然后解锁mutex

			if (i == 3)  throw   logic_error("发生异常了!");

			cout << "A打印" << i << endl;

			//m.unlock();//抛出异常时,导致没有unlock,使得B无法获取mutex, 死锁

		}

	}
	catch (logic_error  & e)
	{
		cout << "错误" <<e.what()<< endl;
	}

}

void  ThreadFun2()
{
	for (int i = 0; i < 10; ++i)
	{
		sleep_for(chrono::seconds(1));

		lock_guard<mutex>   lck(m);

		//m.lock(); 
		cout << "B打印" << i << endl; 
		//m.unlock(); 
	}
}


int  main()
{

	thread  t1(ThreadFun);
	thread  t2(ThreadFun2);

	t1.join();
	t2.join();


	return 0;
}

#endif

#if 0//独占锁
#include<iostream>
#include<mutex>
#include<thread>
#include<stdexcept>
using namespace std;
using namespace std::this_thread;
mutex m;
void threadFun1(){
	try{
		for (int i = 0; i < 10; i++)
		{
			unique_lock<mutex> lck(m);
			//m.lock();//
			if (i == 3)
				throw logic_error("发生异常了!");
			cout << "A 打印: " << i << endl;

			//m.unlock();//使用lck.lock()主动上锁,当抛出异常时,导致没有unlock,使得B无法获取mutex,死锁
			//但是使用unique_lock则不会出现死锁的情况,离开作用于会自动解锁,但是也可以手动lck.unlock()来手动解锁
			sleep_for(chrono::seconds(1));
		}
	}
	catch (logic_error &e){
		cout << "错误" << e.what() << endl;
	}
}
void threadFun2(){
	for (int i = 0; i < 10; i++)
	{
		unique_lock<mutex> lok(m);
		cout << "打印B: " << i << endl;
		//lok.unlock();//可以手动解锁,也可以不用
		sleep_for(chrono::seconds(1));
	}
}
int main()
{
	thread t1(threadFun1);
	thread t2(threadFun2);

	t1.join();
	t2.join();

	system("pause");
	return 0;
}
#endif

#if  0
#include<iostream>
#include<mutex>
#include<condition_variable>
#include<thread>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;

condition_variable cv;//仅支持unique_lock<mutex>作为wait的参数
condition_variable_any cv2;//接受任何lockable参数作为wait的参数
mutex m;

void ThreadFun(int id){
	unique_lock<mutex> lck(m);

	cv.wait(lck);//等待被唤醒,否则一直卡在这里
	cout << "线程ID: " << id << "执行!" << endl;
}

int main(){
	thread t1(ThreadFun, 1);
	thread t2(ThreadFun, 2);
	thread t3(ThreadFun, 3);

	cout << "3秒后被唤醒" << endl;

	sleep_for(seconds(3));//3秒后被唤醒

	//cv.notify_all();//唤醒所有线程
	t1.join();
	t2.join();
	t3.join();
	system("pause");
	return 0;
}

#endif

#if 0 //async线程异步
#include<iostream>
#include<future>
#include<thread>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;

int work(int a, int b)
{
	cout << "开始计算:" << endl;
	sleep_for(seconds(5));//假设某个计算需要耗时5s
	return a + b;
}
int main(){
	future<int> result = async(work, 123, 456);//线程同步函数
	result.wait(); //等待线程结束运行
	cout << "算出结果:" << endl;
	int sum = result.get();//获取线程返回的结果
	cout << "最终的结果是: " << sum << endl;
	system("pause");

	return 0;
}
#endif
#if 0
#include<iostream>
#include<future>
#include<thread>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;

void work(promise<int> &prom){
	cout << "开始计算!" << endl;
	sleep_for(seconds(3));
	cout << "计算完成!" << endl;
	prom.set_value(666);//promise 设置结果值 可以被future  get到 
}
int main()
{
	//定义一个promise
	promise<int> prom;
	//future 和 promise 搭配使用,类似于aynsc
	future<int> result = prom.get_future();

	thread t1(work, ref(prom));
	t1.detach();

	int sum = result.get();
	cout << "获取结果:" << sum << endl;

	system("pause");

	return 0;
}
   

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值