如何通过循环以正确的方式实现std ::线程?

发布于 2025-02-07 08:17:36 字数 4149 浏览 1 评论 0原文

我正在尝试在程序中创建一个多线程部分,其中循环创建多个线程,该线程由沿某些整数沿对象组成的向量和矢量组成,并保存结果。 问题是我似乎无法围绕线程零件的工作方式缠住我的头,我尝试了不同的事情,但都以相同的三个错误结束。 这是我不知道如何进行的地方:

std::thread thread_superdiecreator;

for (int64_t i = 0; i < dicewithside.back().sides; i++) {
    thread_superdiecreator(func_multicreator(dicewithside, i, amount, lastdiepossibilities, superdie));
}

术语不评估为1个参数的函数

我尝试了以下方法:

thread_superdiecreator(func_multicreator, dicewithside, i, amount, lastdiepossibilities, superdie);

呼叫类型的对象,没有适当的操作员()或转换函数到指针对功能类型

,这是:

std::thread thread_superdiecreator(func_multicreator, dicewithside, i, amount, lastdiepossibilities, superdie);

在线程中调用错误。

整个代码段:

#pragma once
#include <mutex>
#include <thread>
#include <algorithm>
#include "class_Diewithside.h"
#include "struct_Sortedinput.h"
#include "func_maximumpossibilities.h"

std::mutex superdielock;


void func_multicreator(std::vector<Diewithside> dicewithside, int64_t lastdieside, int64_t size, int64_t lastdiepossibilities, std::vector<int64_t> &superdie) {
    
    // Set the last die side to number of the thread
    dicewithside[size-1].dieside = lastdieside;
    //
    std::vector<int64_t> partsuperdie;
    partsuperdie.reserve(lastdiepossibilities);

    // Calculate all possible results of all dice thrown with the last one set
    for (int64_t i = 0; i < lastdiepossibilities; i++) {
        
        // Reset the result
        int64_t result = 0;
        for (int64_t j = 0; j < size; j++) {
            result += dicewithside[j].alleyes[dicewithside[j].dieside];
        }
        partsuperdie.push_back(result);

        //
        for (int64_t j = 0; j < size - 1; j++) {
            if (dicewithside[j].dieside == dicewithside[j].sides - 1) {
                dicewithside[j].dieside = 0;
            }
            else {
                dicewithside[j].dieside += 1;
                break;
            }
        }
    }

    superdielock.lock();
    for (int64_t i = 0; i < lastdiepossibilities; i++) {
        superdie.push_back(partsuperdie[i]);
    }
    superdielock.unlock();
}



// The function superdie creates an array that holds all possible outcomes of the dice thrown
std::vector<int64_t> func_superdiecreator(sortedinput varsortedinput) {

    // Get the size of the diceset vector and create a new vector out of class Diewithside
    int64_t size = varsortedinput.dicesets.size();
    std::vector<Diewithside> dicewithside;

    // Initialize the integer amount and iterate through all the amounts of vector dicesets adding them together to set the vector dicewithside reserve
    int64_t amount = 0;
    for (int64_t i = 0; i < size; i++) {
        amount += varsortedinput.dicesets[i].amount;
    }
    dicewithside.reserve(amount);

    // Fill the new vector dicewithside with each single die and add the starting value of 0
    for (int64_t i = 0; i < size; i++) {
        for (int64_t j = 0; j < varsortedinput.dicesets[i].amount; j++) {
            dicewithside.push_back(Diewithside{varsortedinput.dicesets[i].plusorminus, varsortedinput.dicesets[i].sides, varsortedinput.dicesets[i].alleyes, 0});
        }
    }

    // Get the maximum possibilities and divide by sides of the last die to get the amount of iterations each thread has to run
    int64_t maximumpossibilities = func_maximumpossibilities(varsortedinput.dicesets, size);
    int64_t lastdiepossibilities = maximumpossibilities / dicewithside[amount-1].sides;

    // Multithread calculate all possibilities and save them in array
    std::vector<int64_t> superdie;
    superdie.reserve(maximumpossibilities);

    std::thread thread_superdiecreator;
    
    for (int64_t i = 0; i < dicewithside.back().sides; i++) {
        thread_superdiecreator(func_multicreator(dicewithside, i, amount, lastdiepossibilities, superdie));
    }

    thread_superdiecreator.join();

    return superdie;

感谢您的任何帮助!

I´m trying to create a multithread part in my program, where a loop creates multiple threads, that get a vector consisting of objects along some integers and the vector which holds the results.
The problem is I can´t seem to wrap my head around how the thread part works, I tried different things but all end in the same three errors.
This is where I don´t know how to proceed:

std::thread thread_superdiecreator;

for (int64_t i = 0; i < dicewithside.back().sides; i++) {
    thread_superdiecreator(func_multicreator(dicewithside, i, amount, lastdiepossibilities, superdie));
}

term does not evalutate to a function taking 1 arguments

I tried this:

thread_superdiecreator(func_multicreator, dicewithside, i, amount, lastdiepossibilities, superdie);

call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type

And this:

std::thread thread_superdiecreator(func_multicreator, dicewithside, i, amount, lastdiepossibilities, superdie);

Invoke error in thread.

The whole code snippet:

#pragma once
#include <mutex>
#include <thread>
#include <algorithm>
#include "class_Diewithside.h"
#include "struct_Sortedinput.h"
#include "func_maximumpossibilities.h"

std::mutex superdielock;


void func_multicreator(std::vector<Diewithside> dicewithside, int64_t lastdieside, int64_t size, int64_t lastdiepossibilities, std::vector<int64_t> &superdie) {
    
    // Set the last die side to number of the thread
    dicewithside[size-1].dieside = lastdieside;
    //
    std::vector<int64_t> partsuperdie;
    partsuperdie.reserve(lastdiepossibilities);

    // Calculate all possible results of all dice thrown with the last one set
    for (int64_t i = 0; i < lastdiepossibilities; i++) {
        
        // Reset the result
        int64_t result = 0;
        for (int64_t j = 0; j < size; j++) {
            result += dicewithside[j].alleyes[dicewithside[j].dieside];
        }
        partsuperdie.push_back(result);

        //
        for (int64_t j = 0; j < size - 1; j++) {
            if (dicewithside[j].dieside == dicewithside[j].sides - 1) {
                dicewithside[j].dieside = 0;
            }
            else {
                dicewithside[j].dieside += 1;
                break;
            }
        }
    }

    superdielock.lock();
    for (int64_t i = 0; i < lastdiepossibilities; i++) {
        superdie.push_back(partsuperdie[i]);
    }
    superdielock.unlock();
}



// The function superdie creates an array that holds all possible outcomes of the dice thrown
std::vector<int64_t> func_superdiecreator(sortedinput varsortedinput) {

    // Get the size of the diceset vector and create a new vector out of class Diewithside
    int64_t size = varsortedinput.dicesets.size();
    std::vector<Diewithside> dicewithside;

    // Initialize the integer amount and iterate through all the amounts of vector dicesets adding them together to set the vector dicewithside reserve
    int64_t amount = 0;
    for (int64_t i = 0; i < size; i++) {
        amount += varsortedinput.dicesets[i].amount;
    }
    dicewithside.reserve(amount);

    // Fill the new vector dicewithside with each single die and add the starting value of 0
    for (int64_t i = 0; i < size; i++) {
        for (int64_t j = 0; j < varsortedinput.dicesets[i].amount; j++) {
            dicewithside.push_back(Diewithside{varsortedinput.dicesets[i].plusorminus, varsortedinput.dicesets[i].sides, varsortedinput.dicesets[i].alleyes, 0});
        }
    }

    // Get the maximum possibilities and divide by sides of the last die to get the amount of iterations each thread has to run
    int64_t maximumpossibilities = func_maximumpossibilities(varsortedinput.dicesets, size);
    int64_t lastdiepossibilities = maximumpossibilities / dicewithside[amount-1].sides;

    // Multithread calculate all possibilities and save them in array
    std::vector<int64_t> superdie;
    superdie.reserve(maximumpossibilities);

    std::thread thread_superdiecreator;
    
    for (int64_t i = 0; i < dicewithside.back().sides; i++) {
        thread_superdiecreator(func_multicreator(dicewithside, i, amount, lastdiepossibilities, superdie));
    }

    thread_superdiecreator.join();

    return superdie;

Thanks for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情深缘浅 2025-02-14 08:17:36

您确实需要使用问题中提到的第三个替代方案来创建线程,即使用std :: thread启动线程的构造函数。

这种方法的问题是func_multicreator的最后一个参数是lvalue参考:std :: thread创建参数的副本,并在调用函数的过程中移动这些副本背景线程和RVALUE参考不能隐式转换为LVALUE参考。您需要使用std :: Referent_wrapper在这里可以“传递”对线程的LVALUE引用。

您应该加入创建的每个线程,以便您需要创建一个线程集合。

简化的示例:(

有趣的东西在----...注释之间。

struct Diewithside
{
    int64_t sides;
};

void func_multicreator(std::vector<Diewithside> dicewithside, int64_t lastdieside, int64_t size, int64_t lastdiepossibilities, std::vector<int64_t>& superdie)
{
}

std::vector<int64_t> func_superdiecreator() {
    std::vector<Diewithside> dicewithside;

    // Initialize the integer amount and iterate through all the amounts of vector dicesets adding them together to set the vector dicewithside reserve
    int64_t amount = 0;
    int64_t lastdiepossibilities = 0;

    std::vector<int64_t> superdie;

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

    std::vector<std::thread> threads;

    for (int64_t i = 0; i < dicewithside.back().sides; i++) {
        // create thread using constructor std::thread(func_multicreator, dicewithside, i, amount, lastdiepossibilities, std::reference_wrapper(superdie));
        threads.emplace_back(func_multicreator, dicewithside, i, amount, lastdiepossibilities, std::reference_wrapper(superdie));
    }

    for (auto& t : threads)
    {
        t.join();
    }

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

    return superdie;
}

You indeed need to create the thread using the third alternative mentioned in the question, i.e. use the constructor of std::thread to start the thread.

The issue with this approach is the fact the last parameter of func_multicreator being a lvalue reference: std::thread creates copies of parameters and moves those copies during for calling the function on the background thread, and an rvalue reference cannot be implicitly converted to an lvalue reference. You need to use std::reference_wrapper here to be able to "pass" an lvalue reference to the thread.

You should join every thread created so you need to create a collection of threads.

Simplified example:

(The interesting stuff is between the ---... comments.)

struct Diewithside
{
    int64_t sides;
};

void func_multicreator(std::vector<Diewithside> dicewithside, int64_t lastdieside, int64_t size, int64_t lastdiepossibilities, std::vector<int64_t>& superdie)
{
}

std::vector<int64_t> func_superdiecreator() {
    std::vector<Diewithside> dicewithside;

    // Initialize the integer amount and iterate through all the amounts of vector dicesets adding them together to set the vector dicewithside reserve
    int64_t amount = 0;
    int64_t lastdiepossibilities = 0;

    std::vector<int64_t> superdie;

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

    std::vector<std::thread> threads;

    for (int64_t i = 0; i < dicewithside.back().sides; i++) {
        // create thread using constructor std::thread(func_multicreator, dicewithside, i, amount, lastdiepossibilities, std::reference_wrapper(superdie));
        threads.emplace_back(func_multicreator, dicewithside, i, amount, lastdiepossibilities, std::reference_wrapper(superdie));
    }

    for (auto& t : threads)
    {
        t.join();
    }

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

    return superdie;
}
命硬 2025-02-14 08:17:36
std::thread thread_superdiecreator;

单个std :: thread对象总是表示单个执行线程。您似乎正在尝试使用此单个对象来表示多个执行线程。无论您尝试什么,它都行不通。您需要多个std ::线程对象,每个执行线程一个。

thread_superdiecreator(func_multicreator, dicewithside, i, amount, lastdiepossibilities, superdie);

实际执行线程由 构造 新的std :: thread对象,而不是通过将其调用为函数。

构建执行线程对象对应于创建新的执行线程,这很简单。拥有多个执行线程的最简单方法是具有其中的向量。

std::vector<std::thread> all_execution_threads.

有了这一点,创建一个新的执行线程只不过是构建新的std :: thread对象和 移动 它进入向量。或者,更好的是,直接将其放置:

all_execution_threads.emplace_back(
     func_multicreator, dicewithside, i,
     amount, lastdiepossibilities, superdie
);

这假定其他所有内容都是正确的:func_multicreator与以下参数一致,它们都不是通过引用传递(您需要修复此问题,至少需要解决此问题,要将引用传递到线程函数),将悬空的引用留在后面,所有对所有对象都通过多个执行线程访问所有对象,并在使用多个执行线程时正确同步,与互斥词以及所有其他常规的陷阱。但这涵盖了创建一些未指定数量的多个,并发执行线程的基础。当所有人说和完成时,您最终都会得到std :: vector of std :: thread s,一个用于每个实际执行线程。

std::thread thread_superdiecreator;

A single std::thread object always represents a single execution threads. You seem to be trying to use this single object to represent multiple execution threads. No matter what you will try, it won't work. You need multiple std::thread objects, one for each execution thread.

thread_superdiecreator(func_multicreator, dicewithside, i, amount, lastdiepossibilities, superdie);

An actual execution thread gets created by constructing a new std::thread object, and not by invoking it as a function.

Constructing an execution thread object corresponds to the creation of a new execution thread, it's just that simple. And the simplest way to have multiple execution threads is to have a vector of them.

std::vector<std::thread> all_execution_threads.

With that in place, creating a new execution thread involves nothing more than constructing a new std::thread object and moving it into the vector. Or, better yet, emplace it directly:

all_execution_threads.emplace_back(
     func_multicreator, dicewithside, i,
     amount, lastdiepossibilities, superdie
);

This presumes that everything else is correct: func_multicreator agrees with the following parameters, none of them are passed by reference (you need to fix this, at least, your attempt to pass a reference into a thread function will not work), leaving dangling references behind, all access to all objects by multiple execution threads are correctly synchronized, with mutexes, and all the other usual pitfalls when working with multiple execution threads. But this covers the basics of creating some unspecified number of multiple, concurrent, execution threads. When all and said and done you end up with a std::vector of std::threads, one for each actual execution thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文