简体   繁体   English

std ::非无效函数的线程(C ++ 11)

[英]std::Threads of non-void functions ( C++11 )

How can i get the return of the functions sent to the std::threads? 我如何获得返回到std :: threads的函数的返回? I'm working ina function that apllies a filter, created to 2d Images, in each channel of an color/multispectral image. 我正在使用一个功能,该功能在彩色/多光谱图像的每个通道中添加一个为2d图像创建的滤镜。 But many of the functions previously implemented in this library have an image as return, i tried to create a function that takes the return image as a parameter, but it didn't work. 但是以前在该库中实现的许多功能都有一个图像作为返回值,我试图创建一个将返回图像作为参数的函数,但是它不起作用。 Here's a copy of the code: 这是代码的副本:

template< class D, class A >
  template < typename... Args>
  void Image < D, A >::VoidFunction( Image< D, A > &out, Image < D, A > function ( const Image< D, A >& , Args ... ),
                     const Image <D, A > &in, Args... args ) {
    out = ( function ) ( in, args... );
    return ;
  }

  template< class D, class A >
  template < typename... Args>
  Image < D, A > Image < D, A >::multiSpecImgFilter( Image < D, A > function ( const Image<D, A>& , Args ... ),
                             const Image <D, A > &img, Args... args ) {   
    if ( img.Dims() != 3 ) {
      std::string msg( std::string( __FILE__ ) + ": " + std::to_string( __LINE__ ) + ": Image<D,A> " + "::" + 
               std::string( __FUNCTION__ ) + ": error: Image channels must have 2 dimensions" );
      throw( std::logic_error( msg ) );
    }
    std::vector< Image < D, A > > channel = img.Split( );  
    // std::vector< std::thread > threads ;
    // for( size_t thd = 0; thd < channel.size(); ++thd )
    //   threads[ thd ].join( );

    try {
      for ( int ch = 0; ch < channel.size() ; ch++ )
    std::thread thd ( &VoidFunction, channel[ch], function, channel[ch], args... );
    }
    catch( ... ) { 
      for ( int ch = 0; ch < img.size(2) ; ch++ )
        channel[ ch ] = ( function ) ( channel [ ch ], args... );
    }
    return ( Image< D, A >::Merge( channel, img.PixelSize().back(), img.Channel().back() ) );  
  }

You can use a lambda and store the result in it. 您可以使用lambda并将结果存储在其中。

#include <iostream>
#include <thread>

int threadFunction()
{
    return 8;
}


int main()
{
    int retCode;
    //retCode is captured by ref to be sure the modifs are also in the main thread
    std::thread t([&retCode](){
        std::cout << "thread function\n";
        retCode=threadFunction();
    });
    std::cout << "main thread\n";//this will display 8
    t.join();//to avoid a crash
    return 0;
}

or pass by std::ref. 或通过std :: ref。 This is an example from : https://www.acodersjourney.com/c11-multithreading-tutorial-via-faq-thread-management-basics/ 这是一个示例: https//www.acodersjourney.com/c11-multithreading-tutorial-via-faq-thread-management-basics/

#include <string>
#include <thread>
#include <iostream>
#include <functional>
using namespace std;
void ChangeCurrentMissileTarget(string& targetCity)
{
  targetCity = "Metropolis";
  cout << " Changing The Target City To " << targetCity << endl;
}
int main()
{
  string targetCity = "Star City";
  thread t1(ChangeCurrentMissileTarget, std::ref(targetCity));
  t1.join();
  cout << "Current Target City is " << targetCity << endl;
  return 0;
}

The canonical way of doing this, I suppose, is to use async . 我想,规范的做法是使用async

#include <functional>
#include <future>
#include <iostream>

int main()
{
    auto result = std::async(std::launch::async, std::plus<>{}, 42, 42);
    std::cout << result.get() << "\n"; // outputs 84
}

( live demo ) 现场演示

I'd say this looks better than using an output parameter. 我说这看起来比使用输出参数更好。


You can also directly use a packaged_task : 您也可以直接使用packaged_task

#include <functional>
#include <future>
#include <iostream>

int main()
{
    std::packaged_task<int(int, int)> task{std::plus<>{}};
    auto result = task.get_future();

    std::thread t{std::move(task), 42, 42};
    std::cout << result.get() << "\n"; // outputs 84

    t.join();
}

( live demo ) 现场演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM