我試圖在我的程式中創建一個多執行緒部分,其中一個回圈創建多個執行緒,這些執行緒得到一個由沿一些整數的物件組成的向量和保存結果的向量。問題是我似乎無法理解執行緒部分的作業原理,我嘗試了不同的方法,但都以相同的三個錯誤結束。這是我不知道如何進行的地方:
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);
在沒有適當的 operator() 或將函式轉換為指標函式型別的情況下呼叫型別別的物件
和這個:
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;
謝謝你的幫助!
uj5u.com熱心網友回復:
您確實需要使用問題中提到的第三種替代方法來創建執行緒,即使用建構式std::thread來啟動執行緒。
這種方法的問題在于最后一個引數func_multicreator是左值參考:std::thread創建引數的副本并在后臺執行緒上呼叫函式期間移動這些副本,并且右值參考不能隱式轉換為左值參考。您需要在std::reference_wrapper此處使用才能將左值參考“傳遞”給執行緒。
您應該加入創建的每個執行緒,因此您需要創建執行緒集合。
簡化示例:
(有趣的東西在---...評論之間。)
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;
}
uj5u.com熱心網友回復:
std::thread thread_superdiecreator;
單個std::thread物件始終代表單個執行執行緒。您似乎正在嘗試使用這個單個物件來表示多個執行執行緒。無論你嘗試什么,它都行不通。您需要多個std::thread物件,每個執行執行緒一個。
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::vectorof std::threads,每個實際執行執行緒都有一個。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/490204.html
