0

此代码仅在/* debug messages */未注释下的任何行时才有效。或者,如果映射到的列表少于 30 个元素。

func_map是 Lisp 样式映射的线性实现,可以假设它可以工作。

它的使用如下func_map(FUNC_PTR foo, std::vector* list, locs* start_and_end)

FUNC_PTR是一个指向函数的指针,该函数返回void并接收一个int指针

例如:&foo其中foo定义为:

void foo (int* num){ (*num) = (*num) * (*num);}

locs是一个有两个成员的结构int_startint_end; 我用它来告诉func_map它应该迭代哪些元素。

void par_map(FUNC_PTR func_transform, std::vector<int>* vector_array) //function for mapping a function to a list alla lisp
{
    int array_size = (*vector_array).size(); //retain the number of elements in our vector
    int num_threads = std::thread::hardware_concurrency(); //figure out number of cores    
    int array_sub = array_size/num_threads; //number that we use to figure out how many elements should be assigned per thread

    std::vector<std::thread> threads; //the vector that we will initialize threads in
    std::vector<locs> vector_locs; // the vector that we will store the start and end position for each thread

    for(int i = 0; i < num_threads && i < array_size; i++)
    {
        locs cur_loc; //the locs struct that we will create using the power of LOGIC
        if(array_sub == 0) //the LOGIC
        {
            cur_loc.int_start = i; //if the number of elements in the array is less than the number of cores just assign one core to each element
        }
        else
        {
            cur_loc.int_start = (i * array_sub); //otherwise figure out the starting point given the number of cores
        }

        if(i == (num_threads - 1))
        {
            cur_loc.int_end = array_size; //make sure all elements will be iterated over
        }
        else if(array_sub == 0)
        {
            cur_loc.int_end = (i + 1); //ditto
        }
            else
            {
                cur_loc.int_end = ((i+1) * array_sub); //otherwise use the number of threads to determine our ending point
            }

        vector_locs.push_back(cur_loc); //store the created locs struct so it doesnt get changed during reference
        threads.push_back(std::thread(func_map,
                                  func_transform,
                                   vector_array,
                                    (&vector_locs[i]))); //create a thread

        /*debug messages*/ // <--- whenever any of these are uncommented the code works
        //cout << "i = " << i << endl;
        //cout << "int_start == " << cur_loc.int_start << endl;
        //cout << "int_end == " << cur_loc.int_end << endl << endl;
        //cout << "Thread " << i << " initialized" << endl; 

    }

    for(int i = 0; i < num_threads && i < array_size; i++)
    {
        (threads[i]).join(); //make sure all the threads are done
    }
}

我认为问题可能在于如何vector_locs[i]使用以及如何解决线程。但是使用向量来维护locs线程引用的实例的状态应该可以防止它成为问题;我真的很难过。

4

2 回答 2

0

我认为你应该把这个循环放在主循环内部:

 ...
 for(int i = 0; i < num_threads && i < array_size; i++)
 {
   (threads[i]).join(); //make sure all the threads are done
 }
}
于 2014-03-10T06:26:48.400 回答
0

您正在给线程函数一个指针, ,随着您将更多项目放入向量中&vector_locs[i],该指针可能会失效。由于您事先知道将包含 多少项目- 您可以提前该空间以防止重新分配。push_back
vector_locsmin(num_threads, array_size)reserve

至于为什么取消注释输出不会崩溃,我猜是输出太慢了,以至于你刚刚启动的线程会在输出完成之前完成,所以下一次迭代不会影响它。

于 2014-03-10T06:54:02.827 回答