我如何在 C++ 中使用异步函数?

Posted

技术标签:

【中文标题】我如何在 C++ 中使用异步函数?【英文标题】:How may i use asynchronous functions in C++? 【发布时间】:2014-12-10 20:07:59 【问题描述】:

我是一名初学者 C++ 程序员。我知道语句将逐行执行,所以如果我在 main 中调用一个函数,则被调用函数的主体将首先执行,然后是其余代码...

如下代码所示:

int main()

 ABC();
 // ...


void ABC()

// ...

所以我当前程序的执行是同步的,但我希望它是异步的

抱歉标题不好!我找不到更好的问题标题!如果你可以请编辑它。

感谢您对像我这样的初学者程序员的帮助:D

【问题讨论】:

这不是一个简单的主题,需要更新的编译器(基于标准)或库或操作系统支持 如果您想异步执行其他代码的代码,您需要创建一个线程或进程来执行该代码。 @ikegami 你能推荐一个多线程的快速教程吗? 你也可以看看 boost asio,但如果你是初学者并且可以使用 c++11,那么坚持标准库可能会更简单。 【参考方案1】:

提供例子而不是把初学者指向一篇长文章。提供的文章或链接可能随时下线,从而导致人们再次提出相同的问题。

异步通常不适合初学者,但由于您想学习它,这里有一个如何做的例子。您可以复制代码并粘贴它然后运行它。研究代码。他们的评论很好,你可以理解。 看看哪一种最适合您。

方法一: 需要 C++ 11

应该适用于 Windows、Mac 和 Linux*

 #include <iostream>
    #include <future> //Import the asynchronous Library

    using namespace std;

    //The function you want to call asynchronously
    void ABC()
    
    cout<<"Hello From ABC Function"<<endl;
    

    int main()
    
        /*Setup **ABC function**, We will call it **MyABCFunction**, but you can call it anything else.
       Inside MyABCFunction, we call **sync function** and pass it the name of the **function** we want
        to call which is "ABC()". You don't include the "()", just the name "ABC".*/

      future<void> MyABCFunction(async(ABC));

      //Call ABC function
      MyABCFunction.get();


      //Show message from the Main Function
      cout << "Hello From Main Function." <<endl;
      return 0;
    

由于您是 C++ 新手,我将提到您不应该使用“using namespace std”,因为它可能导致程序变大和其他命名冲突。

让我们在下面修复它:

    #include <iostream>
    #include <future> //Import the asynchronous Library

    /*No "using namespace std". Instead, each c++ library function must be begin with "std::"
    which includes Standard library for the function needed
    */

    //The function you want to call asynchronously
    void ABC()
    
        //std:: before cout and endl
       std::cout<<"Hello From ABC Function"<<std::endl;
    

    int main()
    
      //std:: before future and async
      std::future<void> MyABCFunction(std::async(ABC));

      //Call ABC function
      MyABCFunction.get();

      //std:: before cout and endl
      std::cout << "Hello From Main Function." <<std::endl;
      return 0;
    

方法二:

C++ 11 不需要

仅适用于 Windows(最简单快捷的方法)

#include <iostream> //For text on screen
#include <windows.h>  //Must include the use HANDLE class
#include <process.h>   // needed for _beginthread()

//Function prototype of ABCD function to be called in a thread.
void ABCD(void *param);

int main()



    int val = 0;
    HANDLE handle; //Create a handle (Only on Windows OS)

    /*Initialize the handle and begin thread. */
    /*_beginthread takes the name of the function to be called "ABCD" */
    /*_beginthread takes the stack size of the thread 0*/
    /*_beginthread takes the parameter to be passed to the "ABCD" which is 0(val) since void ABCD(void *param) takes void which means no parameter*/

    handle = (HANDLE) _beginthread( ABCD,0,&val);

 /*Do infinite loop on the main function to prove that main and ABCD function are running at the same time*/
    while(1)
    
        std::cout<<"thread from main function"<<std::endl;
    

    //Wait for ACBD to finish before exiting the program
    WaitForSingleObject(handle,INFINITE);
    return 0;


//ABCD function to be called from the thread
void ABCD(void *param)

    /*Do infinite loop on the main function to prove that ABCD and main function are running at the same time*/
    while(1)
    
        std::cout<<"thread from ABCD function"<<std::endl;
    
    _endthread(); // End thread. Won't be called since we are looping forever in while(1) loop


更多关于_beginthread的信息

方法三:

C++ 11 不需要

POSIX 标准适用于 Windows、Mac 和 Linux

我们将在 ABCD 函数中从 1 到 10,000 计数,而在 main 函数中从 1 计数到 5,000。

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

void *ABCD(void *arg)


    //count from 1 to 10000 from the ABCD function thread
    for(int i=1; i<=10000;i++)
    
        std::cout<<"thread from ABCD function "<<i<<std::endl;
    


int main()


    pthread_t myPthread;

    //Create and call the ABCD function to start counting
    pthread_create(&myPthread, NULL, ABCD, NULL);

    //count from 1 to 5,000 from the main function thread
    for(int i=1; i<=5000;i++)
        std::cout<<"thread from main function"<<std::endl;
    

这里的问题是主函数将首先完成计数,因为它最多计数到 5,000,而主函数计数到 10,000。当 main 函数首先完成时,即使 ABCD 函数没有完成计数,它也会终止整个程序。 为了解决这个问题,我们使用 pthread_join 函数等待 ABCD 函数完成,然后我们的程序才能终止。

下面是整个代码:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

void *ABCD(void *arg)


    //count from 1 to 10000 on from ABCD function thread
    for(int i=1; i<=10000; i++)
    
        std::cout<<"thread from ABCD function "<<i<<std::endl;
    


int main()


    pthread_t myPthread;

    //Create and call the ABCD function to start counting
    pthread_create(&myPthread, NULL, ABCD, NULL);

    //count from 1 to 5,000 on from the main function thread
    for(int i=1; i<=5000; i++)
    
        std::cout<<"thread from main function"<<std::endl;
    

    //Wait for ABCD function to finish before we exit
    int a =0;
    pthread_join(myPthread, (void **)&a);

我希望这可以帮助所有 C++ 线程初学者。一旦您了解了我提供的方法 3 的基础知识,我建议您学习 semaphore。 有关pthread_t的更多信息

【讨论】:

感谢您理解我不是专业的开发人员。 我曾经是初学者,所以我知道它是什么样的。【参考方案2】:

如果您使用的是 C++ 11,则可以考虑使用 std::async:

https://solarianprogrammer.com/2012/10/17/cpp-11-async-tutorial/

http://en.cppreference.com/w/cpp/thread/async

否则,您可以轻松:

创建线程

设置定时器

【讨论】:

创建一个线程怎么样?标准库是否提供创建简单线程的工具? 问:你能推荐一个多线程的快速教程吗? A:假设您有一个 C++ 11 编译器,并且假设您想使用 C++11 std::thread,这是一个很好的起点:codeproject.com/Articles/598695/…

以上是关于我如何在 C++ 中使用异步函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用从 Swift 代码调用的线程在 C++ 上创建异步调用函数?

如何在 C++ 中异步读/写?

标准 C++ 中的异步线程

如何在 C++ 中异步执行 curl_multi_perform()?

在 C++ 中处理复合异步函数

颤振/飞镖:如何在飞镖 FFI 中使用异步回调?