第四课:C++带返回值线程处理函数

本文介绍了在C++中如何从线程处理函数获取返回值,包括使用async、future、packaged_task和promise等方法。示例代码展示了普通函数、类成员函数以及lambda表达式的线程处理函数的返回值获取方式。
摘要由CSDN通过智能技术生成

 一,带返回值的普通函数充当线程处理函数

int  returnValue()
{
    return 100;
}

如上述代码段 returnValue() 充当线程处理函数、获取它返回值。

1,采用async:启动一个一异步任务(创建线程,并且执行线程处理函数),返回值future对象
2,通过future对像中的get()方法获取线程返回值

3、如下:

    thread t1(returnValue);
    t1.join();
    
    future<int> result = async(returnValue);
    cout<<result.get()<<endl;

二、带返回值的类成员函数充当线程处理函数

class MM
{
  public:
    int mmThread(int num)
    {
        cout<<"MMthread_ID:"<<this_thread::get_id()<<endl;
        unm *= 2;
        chrono::milliseconds duration(5000);   //延时5000
        this_thread::sleep_for(duration);
        return num;
    }
};

对于带返回值的类成员函数充当线程处理函数、如何获取返回值、又可以进行传叁,构建一个对象 。

如下:(对于其他用法、程序里有解释)

void testAsync()
{

    MM mm;
    auto temp = async(&MM::mmThread,&mm,120);
    cout<<temp.get()<<endl;
    
    //async的其他叁数
    //launch::async      :创建线程,执行线程处理函数
    //launch::deferred   :线程处理函数延时到,调用wait和get方法时候才会执行,本质是没有创建子线程
    
    auto testDerred = async(launch::deferred,&MM::mmThrad,&mm,100);
    cout<<testDerred.get()<<endl;
    auto testAsyncParam = async(launch::async,&MM::mmThrad,&mm,100);  
}

三、用thread处理带返回值的线程处理函数

3.1,通过类模板 packaged_task 包装线程处理函数
3.2,通过packaged_task 的对象调用get_future获取future对像,再通过get()方法得到子线程处理函数的返回值

如下:

void testPackaged_task()
{
    //1,打包普通函数

    packaged_task<int(void)> packOne(returnValue);
    thread testOne(ref(packOne));
    testOne,join();
    cout<<taskOne.get_future().get()<<endl;

    //2,打包类的成员函数

    MM mm;
    packaged_task<int(int)> tasKTow(bind(&MM::mmThread,&mm,Placehoders::_1));
    thread testTow(ref(taskTow),20);
    tesTow.join();
    cout<<testTow.get_future().get()<<endl;

    //3,打包Lanbda表达式

    packaged_task<int(int)> resulthree([](int num)
    {
      cout<<"thread_id"<<this_thread::get_id()<<endl;  
        
        num *= 10;
         return num;
        
    }) ;
    
    thread testTree(ref(resulthree),7);
    resulthree.join();
    cout<<testTree.get_future().get()<<endl;
    
}

四、promise 获取线程处理函数“返回值”


1,通过promise类模板构造建对象,通过调用set_value存储函数需要返回的值
2,通过get_future获取future对象,再通过get()方法获取线程处理函数中的值

如下:

void testPromiseThread(promise<int> & temp,int date)
{
   cout<<"线程ID"<<this_thread::get_id()<<endl; 
    date *= 3;
    temp.set_value(date);
}

void testPromiseTohread(promise<int> &temp)
{
    int num = temp.get_future().get();
    cout<<num<<endl;
}

void testPromise()
{
    promise<int> temp;
    thread testp(testPromiseThread,ref(temp),18);
    testp.join();
    cout<<temp.get_future().get()<<endl;
    //temp.set_value(120);
    
    promise<int> date;
    date.set_value(120);
    auto num = date.get_future();
    thread test(testPromiseToThread,ref(num));
    test.join();
}

五、完整案例

如下:

#include<thread>
#include<ctime>
#include<chrono>
#include<iostream>
#include<time>
#include<iomanip>
#include<future>

using namespace std;
using namespace this_thread;

//1,带返回值的普通函数充当线程处理函数

int  returnValue()
{
    return 100;
}


//2,带返回值的类成员函数充当线程处理函数
class MM
{
  public:
    int mmThread(int num)
    {
        cout<<"MMthread_ID:"<<this_thread::get_id()<<endl;
        unm *= 2;
        chrono::milliseconds duration(5000);   //延时5000
        this_thread::sleep_for(duration);
        return num;
    }
};

void testAsync()
{
    future<int> result = async(testTheradOne);
    cout<<result.get()<<endl;
    MM mm;
    auto temp = async(&MM::mmThread,&mm,120);
    cout<<temp.get()<<endl;
    
    auto testDerred = async(launch::deferred,&MM::mmThrad,&mm,100);
    cout<<testDerred.get()<<endl;
    auto testAsyncParam = async(launch::async,&MM::mmThrad,&mm,100);  
}

//3,用thread处理带返回值的线程处理函数


void testPackaged_task()
{
    //1,打包普通函数

    packaged_task<int(void)> packOne(returnValue);
    thread testOne(ref(packOne));
    testOne,join();
    cout<<taskOne.get_future().get()<<endl;

    //2,打包类的成员函数

    MM mm;
    packaged_task<int(int)> tasKTow(bind(&MM::mmThread,&mm,Placehoders::_1));
    thread testTow(ref(taskTow),20);
    tesTow.join();
    cout<<testTow.get_future().get()<<endl;

    //3,打包Lanbda表达式

    packaged_task<int(int)> resulthree([](int num)
    {
      cout<<"thread_id"<<this_thread::get_id()<<endl;  
        
        num *= 10;
         return num;
        
    }) ;
    
    thread testTree(ref(resulthree),7);
    resulthree.join();
    cout<<testTree.get_future().get()<<endl;
    
}

//4,promise 获取线程处理函数“返回值”


void testPromiseThread(promise<int> & temp,int date)
{
   cout<<"线程ID"<<this_thread::get_id()<<endl; 
    date *= 3;
    temp.set_value(date);
}

void testPromiseTohread(promise<int> &temp)
{
    int num = temp.get_future().get();
    cout<<num<<endl;
}

void testPromise()
{
    promise<int> temp;
    thread testp(testPromiseThread,ref(temp),18);
    testp.join();
    cout<<temp.get_future().get()<<endl;
    //temp.set_value(120);
    
    promise<int> date;
    date.set_value(120);
    auto num = date.get_future();
    thread test(testPromiseToThread,ref(num));
    test.join();
}

int main()
{
    thread t1(returnValue);
    t1.join();
    
    future<int> result = async(returnValue);
    cout<<result.get()<<endl;
    
    testAsync();
    
    
   return 0; 
}

在Visual C++中,获取线程函数的返回值可以通过使用`CreateThread`函数创建线程,并通过等待该线程结束来获取其返回值线程函数的返回值可以通过`ExitThread`函数来设置,该函数接受一个`UINT`类型的参数作为线程的退出代码,这个退出代码可以看作是线程函数的返回值。 具体操作步骤如下: 1. 定义线程函数:确保你的线程函数有一个返回值,其返回类型通常是`UINT`(无符号整数),因为这个返回值将被用作线程的退出代码。 2. 创建线程:使用`CreateThread`函数创建线程,并将线程函数作为参数传递。`CreateThread`函数会返回一个线程句柄。 3. 等待线程结束:使用`WaitForSingleObject`或`WaitForMultipleObjects`函数等待线程结束。这些函数接受线程句柄作为参数,并返回一个等待状态。 4. 获取返回值:一旦线程结束,你可以通过检查`WaitForSingleObject`函数的返回值来确认线程是否成功结束,并使用`GetExitCodeThread`函数获取线程的退出代码,这个退出代码就是线程函数的返回值。 示例代码片段如下: ```cpp #include <windows.h> // 线程函数定义 UINT WINAPI ThreadFunc(LPVOID lpParam) { // ... 线程执行的代码 ... // 假设线程执行完毕后返回值为0 return 0; } // 创建并获取线程返回值 int main() { HANDLE hThread = CreateThread( NULL, // 默认安全属性 0, // 默认堆栈大小 ThreadFunc, // 线程函数 NULL, // 线程函数参数 0, // 默认创建标志 NULL); // 不需要线程ID if (hThread == NULL) { // 处理错误 } // 等待线程结束 WaitForSingleObject(hThread, INFINITE); UINT uExitCode; if (GetExitCodeThread(hThread, &uExitCode)) { // uExitCode 即为线程函数的返回值 } else { // 处理错误 } // 关闭线程句柄 CloseHandle(hThread); return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值