Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 Threads: Error passing a vector to a thread function

I am working on a multithreaded median function as part of a larger project. I have little C++ experience. The median function below should take a vector of 3 dimensional int vectors, and return a 3 dimensional vector of ints where each entry is the median value of all the entries in that index in the input vectors. So if the input is <<3,2,1>,<1,2,3>,<2,2,2>>, the return in <2,2,2>. This code will be used in the implementation of a median blur for use on real-time video, hence the desire to multithread it.

#include <thread>
#include <iostream>
#include <mutex>
#include <vector>
#include <algorithm>
#include "median.h"

// mutex to protect bgrPixel (possibly not needed)
std::mutex mtx;


std::vector<int> median(const std::vector<std::vector<int> >& input)
{
    std::vector<int> bgrPixel;              // Vector to store median BGR value
    std::thread first(thread_function, bgrPixel, input, 0); // thread for each colour channel
    std::thread second(thread_function, bgrPixel, input, 1);
    std::thread third(thread_function, bgrPixel, input, 2);
    first.join();
    second.join();
    third.join(); 
    return bgrPixel;
}

void thread_function(std::vector<int>& bgrPixel, const std::vector<std::vector<int> >&                 input1, int channel)
{

    std::vector<int> input = input1[channel];  // copy the colour channel
    std::sort(input.begin(), input.end());
    int size = input.size();
    if (size %2 == 0)   // get the median
    {
        mtx.lock();
        bgrPixel[channel] = (input[size/2] + input[size/2 + 1])/2;
        mtx.unlock();
    } else
    {
        mtx.lock();
        bgrPixel[channel] = input[(size-1)/2];
        mtx.unlock();
    }
}

The problem I am having is, at compile time, g++ (and clang also) gives a fairly unintelligible error:

 g++ -std=c++11 -pthread -o median median.cpp

 In file included from /usr/include/c++/4.8.2/thread:39:0,
                  from median.cpp:1:
 /usr/include/c++/4.8.2/functional: In instantiation of ‘struct std::_Bind_simple<void           (*(std::vector<int>, std::vector<std::vector<int> >, int))(std::vector<int>&, const      std::vector<std::vector<int> >&, int)>’:
 /usr/include/c++/4.8.2/thread:137:47:   required from ‘std::thread::thread(_Callable&&,           _Args&& ...) [with _Callable = void (&)(std::vector<int>&, const      std::vector<std::vector<int> >&, int); _Args = {std::vector<int, std::allocator<int> >&,      const std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int,      std::allocator<int> > > >&, int}]’
 median.cpp:15:58:   required from here
 /usr/include/c++/4.8.2/functional:1697:61: error: no type named ‘type’ in ‘class                std::result_of<void (*(std::vector<int>, std::vector<std::vector<int> >, int))     (std::vector<int>&, const std::vector<std::vector<int> >&, int)>’
        typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                         ^
 /usr/include/c++/4.8.2/functional:1727:9: error: no type named ‘type’ in ‘class      std::result_of<void (*(std::vector<int>, std::vector<std::vector<int> >, int))     (std::vector<int>&, const std::vector<std::vector<int> >&, int)>’
          _M_invoke(_Index_tuple<_Indices...>)
          ^

I have found a similar error message c++11 Thread class how to use a class member function, but it does not deal specifically with my problem. Any help would be much appreciated, I fully expect this is because I don't know what I am doing :P

EDIT: Prototypes for thread_function and median are included from the header file median.h.

like image 788
chaffdog Avatar asked Apr 24 '14 10:04

chaffdog


People also ask

Is vector in C++ thread safe?

const and Thread Safety The C++11 standard does not expect to be able to safely call non const functions simultaneously. Therefore all classes available from the standard, e.g. std::vector<>, can safely be accessed from multiple threads in the same manner.

How to pass arguments to thread function in c?

Example 1 - Thread Argument Passing long taskids[NUM_THREADS]; for(t=0; t<NUM_THREADS; t++) { taskids[t] = t; printf("Creating thread %ld\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *) taskids[t]); ... } See the source code.

How to pass multiple arguments to a thread function in c?

/* Code Listing 6.9: Passing multiple arguments to a thread requires grouping them into a struct */ /* Assume we have: struct thread_args { int first; const char *second; }; */ struct thread_args *args = malloc (sizeof (struct thread_args)); args->first = 5; args->second = "Hello"; /* Note that the data structure ...

How to return values from threads in c?

If you want to return only status of the thread (say whether the thread completed what it intended to do) then just use pthread_exit or use a return statement to return the value from the thread function.


1 Answers

Replace

std::thread first(thread_function, bgrPixel, input, 0);

by

std::thread first(thread_function, std::ref(bgrPixel), std::ref(input), 0);

Live example: http://coliru.stacked-crooked.com/a/630775aafc3d4642

like image 155
Jarod42 Avatar answered Sep 18 '22 23:09

Jarod42