线程控制块
线程的实体包括程序、数据和线程控制块TCB,TCB包括:
- 线程状态
- 当线程不运行时,被保存的线程资源
- 一组执行堆栈
- 存放每个线程的局部变量主存区
- 访问同一进城中的主存和其他资源
常用API
C语言
头文件#include<Windows.h>
CreateThread
#include <Windows.h>
#include <iostream>
using namespace std;
//windows标准调用约定_stdcall
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter);
int main()
{
DWORD threadId = 0;
HANDLE hThread= CreateThread(NULL, 0, ThreadFun, (void*)"add", 0, &threadId);
if (NULL == hThread)
{
cout << "线程创建失败" << GetLastError() << endl;
}
std::cout << "线程句柄:" << hThread << endl;
cout << "线程的ID:" << threadId << threadId << endl;
}
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter)
{
char*str = (char*)lpThreadParameter;
cout << "启动新线程" <<str<< endl;
return 0;
}
GetCurrentThreadId
DWORD WINAPI GetCurrentThreadId();//得到当前线程ID
CloseHandle
SuspendThread
ResumeThread
Sleep
#include <Windows.h>
#include <iostream>
using namespace std;
//windows标准调用约定_stdcall
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter);
int main()
{
DWORD threadId = 0;
HANDLE hThread= CreateThread(NULL, 0, ThreadFun, (void*)"add", 0, &threadId);
if (NULL == hThread)
{
cout << "线程创建失败" << GetLastError() << endl;
}
cout << "线程句柄:" << hThread << endl;
cout << "子线程的ID:" << threadId << endl;
cout << "主线程ID:" << GetCurrentThreadId() << endl;
//CloseHandle(hThread);//关闭该句柄,表示以后不再引用该句柄
getchar();
SuspendThread(hThread);//挂起线程
getchar();
ResumeThread(hThread);//恢复句柄
getchar();
}
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter)
{
char*str = (char*)lpThreadParameter;
while (true)
{
cout << "线程处理函数" << str << endl;
cout << "子线程ID:" << GetCurrentThreadId() << endl;
Sleep(1000);
}
return 0;
}
WaitForSingleObject
未通知状态:线程的句柄所关联的线程还未结束
#include <Windows.h>
#include <iostream>
using namespace std;
//windows标准调用约定_stdcall
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter);
int main()
{
cout << "主线程开始" << endl;
HANDLE hThread = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
cout << "主线程结尾!" << endl;
getchar();
}
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter)
{
int n = 6;
while (n-->0)
{
cout << "子线程hello" << endl;
Sleep(1000);
}
return 0;
}
ExitThread
TerminateThread
GetExitCodeThread
#include <Windows.h>
#include <iostream>
using namespace std;
//windows标准调用约定_stdcall
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter);
int main()
{
cout << "主线程开始" << endl;
HANDLE hThread = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL);
DWORD code;
GetExitCodeThread(hThread, &code);
if (code==STILL_ACTIVE)
{
cout << "子线程没有退出" << endl;
}
WaitForSingleObject(hThread, INFINITE);//等待子线程退出
GetExitCodeThread(hThread, &code);
cout << "子线程退出嘛:"<<code << endl;
cout << "主线程结尾!" << endl;
getchar();
}
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter)
{
int n = 6;
while (n-->0)
{
cout << "子线程hello" << endl;
Sleep(1000);
if (3 == n)
{
ExitThread(1);
}
}
return 0;
}
WaitForMultipleObjects
#include <Windows.h>
#include <iostream>
using namespace std;
//windows标准调用约定_stdcall
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter);
int main()
{
cout << "主线程开始" << endl;
HANDLE hThread1 = CreateThread(NULL, 0, ThreadFun, (LPVOID)"a", 0, NULL);
HANDLE hThread2 = CreateThread(NULL, 0, ThreadFun, (LPVOID)"b", 0, NULL);
HANDLE hThread3 = CreateThread(NULL, 0, ThreadFun, (LPVOID)"c", 0, NULL);
HANDLE handlesArr[] = { hThread1,hThread2,hThread3 };
//等待所有线程结束
DWORD ret = WaitForMultipleObjects(3, handlesArr, true, INFINITE);
//任一线程结束就返回数组的索引
DWORD ret = WaitForMultipleObjects(3, handlesArr, false, INFINITE);
cout << ret << endl;
cout << "主线程结尾!" << endl;
getchar();
}
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter)
{
char* p = (char*)lpThreadParameter;
if (strcmp(p,"a"))
{
Sleep(1000);
}
if (strcmp(p, "b"))
{
Sleep(2000);
}
if (strcmp(p, "c"))
{
Sleep(3000);
}
cout << p << endl;
return 0;
}
C++ 语言
#include <process.h>
_beginthread
_endthread
#include <process.h>
#include <iostream>
#include <Windows.h>
using namespace std;
void ThreadFun(void* param);
int main()
{
cout << "主线程开始" << endl;
HANDLE hThread=(HANDLE)_beginthread(ThreadFun, 0, (void*)"hello");
WaitForSingleObject(hThread, INFINITE);
cout << "主线程结束" << endl;
}
void ThreadFun(void* param)
{
int n = 0;
while (++n<=6)
{
if (n == 3)
{
_endthread();//结束_beginthread创建的线程,不要用ExitThread
}
Sleep(500);
cout << "第" << n << "次" << (char*)param <<endl;
}
cout << "子线程结束" << endl;
}
多线程的同步和互斥
异步:各跑各的
同步:接力赛,接棒才可继续
互斥:独木桥,每次只能通过一个人
临界区
类似于电话亭,只能每次进去一个人
#include <process.h>
#include <iostream>
#include <Windows.h>
#include <time.h>
using namespace std;
void SellThread1(void* param);
int tickets = 100;
//1临界区结构
CRITICAL_SECTION Section;
int main()
{
cout << "开始卖票" << endl;
//2初始化临界区
InitializeCriticalSection(&Section);
//创建两个售票窗口
uintptr_t t1 = _beginthread(SellThread1, 0, (void*)"售票1");
uintptr_t t2= _beginthread(SellThread1, 0, (void*)"售票2");
HANDLE hArr[] = { (HANDLE)t1,(HANDLE)t2 };
WaitForMultipleObjects(2, hArr, true, INFINITE);
//5删除临界区
DeleteCriticalSection(&Section);
cout << "开始结束" << endl;
}
void SellThread1(void* param)
{
while (tickets>0)
{
//3进入临界区,防止其他函数访问
//或者使用TryEnterCriticalSection(&Section)这样不会阻塞线程
EnterCriticalSection(&Section);
if (tickets>0)//防止最后卖第0张票的情况
{
Sleep(100);
cout << (char*)param << "卖出第" << tickets-- << "张票" << endl;
}
//4离开临界区
LeaveCriticalSection(&Section);
}
}
线程死锁
信号量
#include <Windows.h>
#include <iostream>
#include <process.h>
#include <string>
using namespace std;
DWORD WINAPI ThreadFun(LPVOID param);
struct Car
{
string name;
DWORD time;
};
HANDLE hSemaphore = INVALID_HANDLE_VALUE;
int main()
{
//只有三个停车位资源
hSemaphore = CreateSemaphore(NULL, 3, 3, L"停车位");
HANDLE hArr[5] = { INVALID_HANDLE_VALUE };
for (size_t i = 0; i < 5; i++)
{
Car* pCar = new Car;
pCar->name = 'A' + i;
cout << "车辆" << pCar->name << endl;
pCar->time = 3 + i * 2;
hArr[i] = CreateThread(NULL, 0, ThreadFun, (LPVOID)pCar, 0, NULL);
}
WaitForMultipleObjects(5, hArr, true, INFINITE);
}
DWORD WINAPI ThreadFun(LPVOID param)
{
//如果停车位资源没有满,就放行
WaitForSingleObject(hSemaphore, INFINITE);
Car* pCar = (Car*)param;
cout << pCar->name << "进入停车场" << " 停车" << pCar->time << "秒" << endl;
Sleep(pCar->time);
cout << pCar->name << "离开停车场" << endl;
//释放一个停车位,信号量+1
ReleaseSemaphore(hSemaphore, 1, NULL);
return 0;
}
互斥量
#include <process.h>
#include <iostream>
#include <Windows.h>
#include <time.h>
using namespace std;
void SellThread1(void* param);
int tickets = 100;
HANDLE mutex = INVALID_HANDLE_VALUE;
int main()
{
//1创建互斥体,此时是有信号状态,第二个参数表示主线程是否要拥有该互斥量
mutex = CreateMutex(NULL, FALSE, L"售票互斥体");
cout << "开始卖票" << endl;
//创建两个售票窗口
uintptr_t t1 = _beginthread(SellThread1, 0, (void*)"售票1");
uintptr_t t2 = _beginthread(SellThread1, 0, (void*)"售票2");
HANDLE hArr[] = { (HANDLE)t1,(HANDLE)t2 };
WaitForMultipleObjects(2, hArr, true, INFINITE);
cout << "开始结束" << endl;
}
void SellThread1(void* param)
{
while (tickets > 0)
{
//2如果这个互斥体为有信号状态(没有现成拥有它),则获取它后继续执行
WaitForSingleObject(mutex, NULL);
if (tickets > 0)//防止最后卖第0张票的情况
{
Sleep(100);
cout << (char*)param << "卖出第" << tickets-- << "张票" << endl;
}
//3释放互斥体
ReleaseMutex(mutex);
}
}
事件
#include <process.h>
#include <iostream>
#include <Windows.h>
#include <time.h>
using namespace std;
void SellThread1(void* param);
int tickets = 100;
HANDLE hEvent = INVALID_HANDLE_VALUE;
int main()
{
//1创建事件对象,此时为自动有信号
hEvent = CreateEvent(NULL, FALSE, TRUE, L"事件对象");
cout << "开始卖票" << endl;
//创建两个售票窗口
uintptr_t t1 = _beginthread(SellThread1, 0, (void*)"售票1");
uintptr_t t2 = _beginthread(SellThread1, 0, (void*)"售票2");
HANDLE hArr[] = { (HANDLE)t1,(HANDLE)t2 };
WaitForMultipleObjects(2, hArr, true, INFINITE);
cout << "开始结束" << endl;
}
void SellThread1(void* param)
{
while (tickets > 0)
{
//2如果这个事件为有信号状态(没有现成拥有它),则获取它后继续执行
//因为是自动的,调用了以下函数对象后,则自动重置为无信号
WaitForSingleObject(hEvent, INFINITE);
if (tickets > 0)//防止最后卖第0张票的情况
{
Sleep(100);
cout << (char*)param << "卖出第" << tickets-- << "张票" << endl;
}
//3让事件对象变为有信号状态
SetEvent(hEvent);
}
}
互斥量和事件都可以像信号量一样实现程序只能打开一例
PV操作
#include <iostream>
#include <process.h>
#include <windows.h>
#include <queue>
using namespace std;
//仓库
queue<int> store;
int StoreSize = 3;//仓库可放三个货物
int ID = 1;//货物ID
//需要两个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)t1 };
WaitForMultipleObjects(2, hArr, TRUE, INFINITE);
CloseHandle(hEvent1);
CloseHandle(hEvent2);
getchar();
}
void ProducerThread(LPVOID param)
{
//不断生产,直到仓库已满
while (TRUE)
{
WaitForSingleObject(hEvent1, INFINITE);
if (store.size()<StoreSize)//有空位
{
int id = ID++;
cout << "生产产品" << id << endl;
store.push(id);
Sleep(100);
}
else
{
ResetEvent(hEvent1);//事件设置为无信号
cout << "仓库已满" << endl;
}
if (store.size() > 0)//仓库有货物
{
SetEvent(hEvent2);
}
}
}
void ConsumerThread(LPVOID param)
{
while (true)
{
//看是否可以去货物
WaitForSingleObject(hEvent2, INFINITE);
if (store.size() > 0)
{
int id = store.front();
store.pop();
Sleep(200);
cout << "---------------取货物" << id << endl;
}
else
{
ResetEvent(hEvent2);
}
if (store.size() < 3)
{
cout << "####仓库有位置,可生产"<< endl;
SetEvent(hEvent1);//通知生产者继续生产货物
}
}
}
线程总结
信号量、互斥、事件都是内核对象,所有都可以使用WaitForSingleObject和CloseHandle
本地存储TLS
#include <windows.h>
#include <iostream>
#include <process.h>
//声明为静态TLS(线程本体存储变量)
_declspec(thread) int N = 0;//每个线程中的值互不影响,每个线程中都有自己的N的拷贝
DWORD WINAPI ThreadFun1(LPVOID param);
DWORD WINAPI ThreadFun2(LPVOID param);
int main()
{
HANDLE hThread1 = CreateThread(NULL, 0, ThreadFun1, NULL, 0, NULL);
HANDLE hThread2 = CreateThread(NULL, 0, ThreadFun2, NULL, 0, NULL);
HANDLE hArr[] = { hThread1,hThread2 };
WaitForMultipleObjects(2, hArr, TRUE, INFINITE);
return 0;
}
DWORD WINAPI ThreadFun1(LPVOID param)
{
while (true)
{
std::cout << "线程1:" << ++N << std::endl;
}
}
DWORD WINAPI ThreadFun2(LPVOID param)
{
while (true)
{
std::cout << "线程2:" << N << std::endl;//线程2中的N永远为0
}
}
//三个线程互不影响,自己打印自己的值
#include <windows.h>
#include <iostream>
#include <process.h>
DWORD WINAPI ThreadFun1(LPVOID param);
DWORD WINAPI ThreadFun2(LPVOID param);
DWORD tlsIndex = 0;//动态TLS的索引
int main()
{
tlsIndex = TlsAlloc();
if (tlsIndex == TLS_OUT_OF_INDEXES)
{
std::cout << "分配TLS索引失败" << std::endl;
return 0;
}
//在主线程中设置一个值
TlsSetValue(tlsIndex, (LPVOID)"cpp");
char* p = (char*)TlsGetValue(tlsIndex);
std::cout << "主线程打印:" <<p<< std::endl;
HANDLE hThread1 = CreateThread(NULL, 0, ThreadFun1, NULL, 0, NULL);
HANDLE hThread2 = CreateThread(NULL, 0, ThreadFun2, NULL, 0, NULL);
HANDLE hArr[] = { hThread1,hThread2 };
WaitForMultipleObjects(2, hArr, TRUE, INFINITE);
TlsFree(tlsIndex);//释放位置
return 0;
}
DWORD WINAPI ThreadFun1(LPVOID param)
{
TlsSetValue(tlsIndex, (LPVOID)"hello");
while (true)
{
char* p = (char*)TlsGetValue(tlsIndex);
//每个线程同一个索引位置的值只属于自己,和其他线程没有关系
std::cout << "线程1:" << p << std::endl;
}
}
DWORD WINAPI ThreadFun2(LPVOID param)
{
TlsSetValue(tlsIndex, (LPVOID)"word");
while (true)
{
char* p = (char*)TlsGetValue(tlsIndex);
//每个线程同一个索引位置的值只属于自己,和其他线程没有关系
std::cout << "线程2:" << p << std::endl;
}
}
多线程间消息通讯
#include <windows.h>
#include <iostream>
#include <process.h>
DWORD WINAPI ThreadFun1(LPVOID param);
DWORD WINAPI ThreadFun2(LPVOID param);
//自定义消息(必须是自定义消息+1)
#define MY_MSG WM_USER+1
int main()
{
DWORD threadID = 0;
//获取第一个线程的ID,方便第二个线程给第一个线程发消息
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);
return 0;
}
DWORD WINAPI ThreadFun1(LPVOID param)
{
//接收第二个线程发来的消息
MSG msg;
while (GetMessage(&msg,NULL,0,0))//如果有消息继续,否则就阻塞
{
switch (msg.message)
{
case MY_MSG:
std::cout << "收到消息:" << msg.wParam << std::endl;
break;
}
}
std::cout << "收到退出消息:" << std::endl;
return 0;
//利用PeekMessage
//MSG msg;
//while (true)
//{
// //马上就返回,不阻塞
// if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
// {
// switch (msg.message)
// {
// case MY_MSG:
// std::cout << "收到消息:" << msg.wParam << std::endl;
// break;
// case WM_QUIT:
// std::cout << "收到QUIT消息" << std::endl;
// return 0;
// }
// }
//}
}
DWORD WINAPI ThreadFun2(LPVOID param)
{
//给第一个线程发消息
DWORD threadID = (DWORD)param;
int N = 1;
while (true)
{
if (N==10)
{
//让第一个线程退出消息循环
PostThreadMessage(threadID, WM_QUIT, (WPARAM)N++, NULL);
break;
}
PostThreadMessage(threadID, MY_MSG, (WPARAM)N++, NULL);
Sleep(500);
}
return 0;
}
C++11 多线程
thread 线程类
#include <thread>
#include <string>
#include <iostream>
using namespace std;
void ThreadFun(const string &s)
{
cout << s.c_str() << endl;
}
int main()
{
//默认构造函数
thread t1;
cout << t1.get_id() << endl;//为0
cout << t1.joinable() << endl;//为0
thread t2(ThreadFun, "dddd");
cout << t2.get_id() << endl;//为0
cout << t2.joinable() << endl;//为0
t2.join();//等待
getchar();
}
this_thread命名空间
#include <iostream>
#include <thread>
#include <string>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;
void ThreadFun(const string& str)
{
cout << "线程ID:" << get_id() << endl;//获取线程ID
while (true)
{
cout << str << endl;
//sleep_for(seconds(1));//休眠1s
sleep_until(system_clock::now() + milliseconds(1000));//当前时间加上1s
}
}
int main()
{
thread t1(ThreadFun, "hello");
cout <<"线程ID:"<< t1.get_id() << endl;
t1.join();
}
atomic 类与 atomic_flag类
#include <iostream>
#include <thread>
#include <string>
#include <atomic>
using namespace std;
atomic<int> N = 0;
void ThreadFun()
{
for (size_t i = 0; i < 10000; i++)
{
++N;//这样保证了原子操作,如果不用atomic则可能得到的数不是20000
}
}
int main()
{
thread t1(ThreadFun);
thread t2(ThreadFun);
t1.join();
t2.join();
cout << N << endl;
}
#include <iostream>
#include <thread>
#include <string>
#include <atomic>
#include <vector>
using namespace std;
atomic<bool> ready = false;
atomic_flag win = ATOMIC_FLAG_INIT;
void Run(int id)
{
while (!ready)//枪没响,不能跑
{
this_thread::yield();//让其他线程先执行
}
for (size_t i = 0; i < 100000; i++)
{
//无需执行,表示跑的过程
}
//如果没有被设置过,返回false
if (!win.test_and_set())//调用后会自动设置,则会返回true
{
cout << id << "赢得第一" << endl;
}
}
int main()
{
//十个选手赛跑
vector<thread> vecPlayers;
for (size_t i = 0; i < 10; i++)
{
vecPlayers.push_back(thread(Run,i));
}
cout << "10个选手已经准备"<< endl;
//预备跑
this_thread::sleep_for(chrono::seconds(3));
cout << "3 2 1预备跑" << endl;
ready = true;
for (thread& t :vecPlayers)
{
t.join();
}
}
互斥类mutex
#include <iostream>
#include <thread>
#include <string>
#include <mutex>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;
int tickets = 100;
mutex m;
void SellThread(const string& str)
{
while (tickets>0)
{
m.lock();//加锁
if (tickets>0)
{
sleep_for(milliseconds(100));
cout<<str<<"卖出" <<tickets-- <<"票" << endl;
}
m.unlock();//解锁
}
}
int main()
{
thread t1(SellThread, "售票窗口A");
thread t2(SellThread, "售票窗口B");
t1.join();
t2.join();
}
//递归加锁就是多次加锁,也要多次解锁
recursive_mutex m;
void SellThread(const string& str)
{
while (tickets>0)
{
m.lock();//加锁
m.lock();
if (tickets>0)
{
sleep_for(milliseconds(10));
cout<<str<<"卖出" <<tickets-- <<"票" << endl;
}
m.unlock();//解锁
m.unlock();//解锁
}
}
timed_mutex m;//指定锁住时间
void SellThread(const string& str)
{
while (tickets>0)
{
m.try_lock_for(milliseconds(10));//锁住10ms
if (tickets>0)
{
sleep_for(milliseconds(10));
cout<<str<<"卖出" <<tickets-- <<"票" << endl;
}
//会自动解锁
}
}
lock_guard类
#include <iostream>
#include <thread>
#include <string>
#include <mutex>
#include <stdexcept>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;
mutex m;
void FunThread1()
{
try
{
for (size_t i = 0; i < 10; i++)
{
sleep_for(chrono::seconds(1));
//m.lock();
lock_guard<mutex> lck(m);//局部作用域
if (i == 3)
{
throw logic_error("发生异常");
}
cout << "A打印" << i << endl;
//m.unlock();//抛出异常,导致无法解锁
}
}
catch (const std::exception& e)
{
cout << "捕捉异常:" << e.what() << endl;
}
}
void FunThread2()
{
for (size_t i = 0; i < 10; i++)
{
sleep_for(chrono::seconds(1));
//m.lock();
lock_guard<mutex> lck(m);
cout << "B打印" << i << endl;
//m.unlock();
}
}
int main()
{
thread t1(FunThread1);
thread t2(FunThread2);
t1.join();
t2.join();
}
unique_lock类
#include <iostream>
#include <thread>
#include <string>
#include <mutex>
#include <stdexcept>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;
mutex m;
void FunThread1()
{
try
{
for (size_t i = 0; i < 10; i++)
{
sleep_for(chrono::seconds(1));
//m.lock();
unique_lock<mutex> lck(m);
if (i == 3)
{
throw logic_error("发生异常");
}
cout << "A打印" << i << endl;
lck.unlock();//更加灵活的控制范围
//m.unlock();//抛出异常,导致无法解锁
}
}
catch (const std::exception& e)
{
cout << "捕捉异常:" << e.what() << endl;
}
}
void FunThread2()
{
for (size_t i = 0; i < 10; i++)
{
sleep_for(chrono::seconds(1));
//m.lock();
unique_lock<mutex> lck(m);
cout << "B打印" << i << endl;
//m.unlock();
}
}
int main()
{
thread t1(FunThread1);
thread t2(FunThread2);
t1.join();
t2.join();
}
conditon_variable类
#include <iostream>
#include <thread>
#include <string>
#include <mutex>
#include <condition_variable>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;
//condition_variable cv;//仅仅支持unique_lock<mutex>作为wait的参数
condition_variable_any cv;//接受任何lockable参数作为wait的参数
mutex m;
void FunThread1(int id)
{
unique_lock<mutex> lck(m);
cv.wait(lck);//等待被唤醒
cout << "线程ID:" << id << "执行!" << endl;
}
int main()
{
thread t1(FunThread1, 1);
thread t2(FunThread1, 2);
thread t3(FunThread1,3);
cout << "3s后唤醒" << endl;
sleep_for(seconds(3));//3s之后唤醒所有的线程
//cv.notify_all();//唤醒所有的线程
cv.notify_one();//只唤醒1个,唤醒那个事随机的
t1.join();
t2.join();
t3.join();
}
future类
#include <iostream>
#include<future>
#include <thread>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;
int sum(int a, int b)//设置费时的加法操作
{
cout << "子线程开始计算" << endl;
sleep_for(seconds(3));
cout << "子线程算出结果" << endl;
return a + b;
}
int main()
{
cout << "主线程开始" << endl;
future<int> result = async(sum, 123, 456);
result.wait();//等待结果算出
int s= result.get();//得到结果
cout << "结果是:" << s << endl;
cout << "主线程结束" << endl;
}
promise类
#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(5));
//设置结果,future会get到
prom.set_value(666);
}
int main()
{
promise<int> prom;//定义一个promise
//future和promise搭配使用,类似于anysc
future<int> result = prom.get_future();
thread t1(Work,ref(prom));
t1.detach();
int s= result.get();
cout << "获取结果" << s << endl;
}
#include <iostream>
#include<future>
#include <thread>
#include <exception>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;
void Work(promise<int>&prom)//费时操作
{
cout << "开始计算" << endl;
sleep_for(seconds(5));
try
{
throw runtime_error("超时");
}
catch (const std::exception& e)
{
//设置异常
prom.set_exception(current_exception());
}
}
int main()
{
promise<int> prom;//定义一个promise
//future和promise搭配使用,类似于anysc
future<int> result = prom.get_future();
thread t1(Work,ref(prom));
t1.detach();
try
{
int s = result.get();
}
catch (const std::exception& e)
{
cout << "结果异常" << e.what() << endl;
}
}
packaged_task类
#include <iostream>
#include<future>
#include <thread>
#include <exception>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;
int Work(int a,int b)//费时操作
{
cout << "开始计算" << endl;
sleep_for(seconds(3));
return a + b;
}
int main()
{
//packaged_task包装了一个可调用的目标
packaged_task<int(int, int)>pack(Work);
future<int> result = pack.get_future();//获取packaged_task内部的future
thread t1(move(pack), 12, 34);//将package_task给线程执行
t1.detach();
int sum = result.get();
cout << "获取结果" << sum << endl;
}
总结
#include <iostream>
#include<future>
#include <thread>
#include <exception>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;
void Work1(promise<int>& prom,int a,int b)//费时操作
{
cout << "开始计算" << endl;
sleep_for(seconds(3));
prom.set_value(a + b);
}
int Work2( int a, int b)//费时操作
{
cout << "开始计算" << endl;
sleep_for(seconds(3));
return a + b;
}
int Work3(int a, int b)//费时操作
{
cout << "开始计算" << endl;
sleep_for(seconds(3));
return a + b;
}
int main()
{
promise<int> prom;//promise内部包装了一个值
future<int> f1 = prom.get_future();//使用成员函数获取future
thread(Work1, ref(prom), 1, 2).detach();
f1.wait();
cout << "计算结果:" << f1.get() << endl;
packaged_task<int(int, int)>task(Work2);
future<int> f2 = task.get_future();
thread(move(task), 11, 22).detach();
f2.wait();
cout << "计算结果:" << f2.get() << endl;
future<int> f3 = async(Work3, 111, 222);
f3.wait();
cout << "计算结果:" << f3.get() << endl;
}
nt Work(int a,int b)//费时操作 { cout << “开始计算” << endl; sleep_for(seconds(3)); return a + b; } int main() { //packaged_task包装了一个可调用的目标 packaged_task<int(int, int)>pack(Work); future result = pack.get_future();//获取packaged_task内部的future thread t1(move(pack), 12, 34);//将package_task给线程执行 t1.detach(); int sum = result.get(); cout << “获取结果” << sum << endl; }
## 总结
[外链图片转存中...(img-F5shF5tT-1643706717965)]
[外链图片转存中...(img-EejJUvza-1643706717966)]
[外链图片转存中...(img-mIQriYcv-1643706717966)]
[外链图片转存中...(img-GxsTynRA-1643706717967)]
```c++
#include <iostream>
#include<future>
#include <thread>
#include <exception>
using namespace std;
using namespace std::this_thread;
using namespace std::chrono;
void Work1(promise<int>& prom,int a,int b)//费时操作
{
cout << "开始计算" << endl;
sleep_for(seconds(3));
prom.set_value(a + b);
}
int Work2( int a, int b)//费时操作
{
cout << "开始计算" << endl;
sleep_for(seconds(3));
return a + b;
}
int Work3(int a, int b)//费时操作
{
cout << "开始计算" << endl;
sleep_for(seconds(3));
return a + b;
}
int main()
{
promise<int> prom;//promise内部包装了一个值
future<int> f1 = prom.get_future();//使用成员函数获取future
thread(Work1, ref(prom), 1, 2).detach();
f1.wait();
cout << "计算结果:" << f1.get() << endl;
packaged_task<int(int, int)>task(Work2);
future<int> f2 = task.get_future();
thread(move(task), 11, 22).detach();
f2.wait();
cout << "计算结果:" << f2.get() << endl;
future<int> f3 = async(Work3, 111, 222);
f3.wait();
cout << "计算结果:" << f3.get() << endl;
}
|