c++ - 将指针作为参数传递给 std::thread 函数 C++11

标签 c++ multithreading c++11 stdthread

我想传递一个指向线程函数的指针,但它返回了

error: attempt to use a deleted function __invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_In...

main中的代码片段

for (int i = 0; i < threadCount; ++i) {
    ptrTabThreads = new std::thread(checkMin, ptrTab[i]);
    ptrTabThreads->join();
    ++ptrTabThreads;
}

以及checkMin函数的代码

void checkMin(int* tab) {
    int sizeOfTable = 0;

    if (tab == ptrTab[threadCount-1])
        sizeOfTable = partSize + additionalNumbers;
    else
        sizeOfTable = partSize;       

    mt.lock();
    for (int i = 0; i < sizeOfTable; ++i) {
        if (tab[i] < minValue) {
            minValue = tab[i];
        }
    }
    mt.unlock(); 
}

其中 ptrTab 是一个指针数组:

int* ptrTab[threadCount];

完整代码为:

#include <iostream>
#include <thread>
#include <condition_variable>
#include <stdlib.h>
#include <climits>

#define threadCount 10
#define numbersCount 75
std::mutex mt;
int minValue = INT32_MAX;
int partSize, additionalNumbers;
int* ptrTab[threadCount];

void checkMin(int value);
void printTab(int *tab);

int main() {
    int tab[numbersCount];
    srand(time(NULL));

    for (int i = 0; i < numbersCount; ++i) {
        tab[i] = rand() % 1000;
        std::cout << " " << tab[i];
    }

    partSize = numbersCount / threadCount;
    additionalNumbers = numbersCount % threadCount;

    for (int i = 0; i < threadCount-1; ++i) {
        int *newTab = new int[partSize];
        ptrTab[i] = newTab;
    }
    int *newTab = new int[partSize+additionalNumbers];
    ptrTab[threadCount-1] = newTab;

    int copiedElements = 0;
    for (int i = 0; i < threadCount-1; ++i) {
        int *tmpTab = ptrTab[i];
        for (int j = 0; j < partSize; j++) {
            tmpTab[j] = tab[copiedElements];
            copiedElements++;
        }
    }
    int *tmpTab = ptrTab[threadCount-1];
    int elementsLeft = numbersCount-copiedElements;
    for (int i = 0; i < elementsLeft; ++i) {
        tmpTab[i] = tab[copiedElements];
        copiedElements++;
    }

    /*for (int i = 0; i < threadCount; ++i) {
        printTab(ptrTab[i]);
    }*/


    //----------------------

    std::thread tabThreads[threadCount];
    std::thread *ptrTabThreads = tabThreads;

    for (int i = 0; i < threadCount; ++i) {
        ptrTabThreads = new std::thread(checkMin, ptrTab[i]);
        ptrTabThreads->join();
        ++ptrTabThreads;
    }

    std::cout << "\n\n" << minValue << "\n\n";

    //for check
    std::cout << "for check: minimal value is ";
    int min = INT32_MAX;
    for (int i = 0; i < numbersCount; ++i) {
        if (tab[i] < min) {
            min = tab[i];
        }
    }
    std::cout << min << "\n\n";

}

void checkMin(int* tab) {
    int sizeOfTable = 0;

    if (tab == ptrTab[threadCount-1]) 
        sizeOfTable = partSize + additionalNumbers;
    else
        sizeOfTable = partSize;        

    mt.lock();
    for (int i = 0; i < sizeOfTable; ++i) {
        if (tab[i] < minValue) {
            minValue = tab[i];
        }
    }
    mt.unlock();
}

void printTab(int *tab) {
    for (int i = 0; i < 10; ++i) {
        std::cout << tab[i] << " ";
    }
    std::cout << "\n\n";
}

感谢您的所有建议。

最佳答案

直接导致编译错误的问题就在这里:

void checkMin(int value);

这是你的函数的原型(prototype),它是不正确的——它应该是

void checkMin(int* value); //<-- not the pointer.

但这不是唯一的!你的代码没有意义。看看这个片段:

std::thread tabThreads[threadCount];
std::thread *ptrTabThreads = tabThreads;

for (int i = 0; i < threadCount; ++i) {
    ptrTabThreads = new std::thread(checkMin, ptrTab[i]);
    ptrTabThreads->join();
    ++ptrTabThreads;
}

所有这些指针跳跃的目的是什么?您的代码中也有泄漏,因为您在 delete 之前修改了从 new 获得的指针。为什么不使用以下简单代码?

std::array<std::thread, threadCount> tabThreads;

for (int i = 0; i < threadCount; ++i) {
    tabThreads[i] = std::thread(checkMin, ptrTab[i]);
    tabThreads[i].join();
}

这仍然没有实际用途(应用程序仍然有效地保持单线程,因为您在创建线程后立即加入线程),但至少,代码是正确的。要真正做一些花哨的多线程,你需要你的循环看起来像下面这样:

for (int i = 0; i < threadCount; ++i)
    tabThreads[i] = std::thread(checkMin, ptrTab[i]);

for (std::thread& t : tabThreads) // so-called range-for loop. Nice thing!
    t.join();

这将使东西并行化!

关于c++ - 将指针作为参数传递给 std::thread 函数 C++11,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37843572/

相关文章:

c++ - C++如何对负数进行按位 "or"运算?

c++ - 从右值到右值引用的 reinterpret_cast

python - 如果不调用 thread.stop() 或 thread.join() 方法,python 中的线程什么时候会死亡?

c++ - 不可复制类数据成员的统一初始化导致gcc错误

c++ - JNI DeleteLocalRef 说明

c++ - 有没有其他方法可以编写代码而不是在 C++ 中使用 switch 语句

c# - 这是一种安全且*相对可行*的异步记录某些事件的方法吗?

ios - Swift 中带有 Firestore 的完成处理程序的替代方案

c++ - 分配不同类型的多维 vector

c++ - 指定对 std::to_string() 的补充?