将抽象对象从主线程发送到其他线程

Send abstract object from main thread to others thread

本文关键字:线程 其他 抽象 对象      更新时间:2023-10-16

我正在做一个比萨店餐厅模拟,其中主线程是接待处,它可以接受订单并将其转换为抽象的披萨对象 APizza,在这个接待处我有一个厨房对象,其中包含由线程(std::list<std::thread> _cooks(表示的厨师列表 我想从接待主线程传递这些抽象比萨饼, 对于我的子线程厨师,我希望他们能够从厨房主线程中的成分库存(库存 *_ingredients(中挑选,我知道我必须使用互斥锁在修改之前锁定配料库存变量,这样许多厨师就不会访问和更改库存中的数据同时做不可预测的行为。

我正在寻找一些方法来传递这些比萨饼,并使我的主要线程厨房原料库存(库存 *_ingredients(库存可以从厨师那里获得。

这是我的架构:


class Reception
{
public:
Reception(double, size_t, size_t);
~Reception();
int Shell();
APizza *MakeOrder(PizzaType, PizzaSize);
void openKitchen();
private:
int parseCommands();
std::map<size_t, pid_t> _kitchenList;
protected:
double _multiplier; //Cooking time multiplier.
size_t _cooks; //Number of cook(s) per kitchen.
size_t _restock; //Time in ms to restock ingredients.
};

class Kitchen
{
public:
Kitchen(double, size_t, size_t);
~Kitchen();
APizza *MakeOrder(PizzaType, PizzaSize);
void Status();
void DispatchPizza(APizza *pizza);
bool isFull();
private:
std::stack<APizza> 
_pizzaWaiting;
std::list<std::thread> _cooks;
Stock *_ingredients;
double _multiplier; //Cooking time multiplier.
size_t _ncooks; //Number of cook(s) per kitchen.
size_t _restock; //Time in ms to restock ingredients.
size_t _ordersNow;
//Pipe _pipe;
};
class Cook
{
public:
Cook(double _multiplier);
~Cook();
void Run();
bool canCook();
void cookPizza(APizza *);
private:
APizza *_currPizza;
bool _isCooking;
double _multiplier;
};

这是我想传递披萨的地方

int Reception::Shell()
{
std::string command;
std::cout << "> ";
std::list<std::string> orders;
APizza *currPizza;
>>    Kitchen *kitch = new Kitchen(_multiplier, _cooks, _restock);
while (1)
{
getline (std::cin, command);
if (!command.compare("exit") || std::cin.eof())
return(0);
else
{
orders = splitStr(command, ';');
}
if (!orders.empty())
{
for (const std::string & order : orders)
{
size_t nPizza = getPizzaNbr(order);
PizzaType tPizza = getPizzaType(order);
PizzaSize sPizza = getPizzaSize(order);
if (nPizza == 0 || tPizza == (PizzaType)0 || sPizza == (PizzaSize)0) {
std::cout << "wrong input: " << nPizza << " " << tPizza << " " << sPizza << std::endl;
continue;
}
std::cout << "good input: " << nPizza << " " << tPizza << " " << sPizza << std::endl;
for (size_t i = 0; i != nPizza; i++)
{   
currPizza = this->MakeOrder(tPizza, sPizza);
//
// SEND this currPizza to to kitchen cook's thread
//
std::cout << "Nouvelle pizza, type: " << currPizza->getType() 
<< " size: " << currPizza->getSize() << std::endl;
}   
}       
}           
std::cout << std::endl << "> ";
}               
return 0;       
}

老实说,刚刚跳过了你的代码,C++中有一个众所周知的技巧,你创建一个封装pthread并将自指针(this(传递给新线程的类,我将添加一些引用,我通常会推荐,创建一个通用的工人抽象类,而 cook 继承自,cook ctor 通过构造函数或一些 setter 函数让它访问这些抽象披萨, 下面是一个示例:

class some_thread
{
public:
some_thread_ctr(pizza_list * your_pizza_list) {};
void start_thead()
{
pthread_create(&i, 0, somethread_main, this);
}
static void * somethread_main(void * somethread_ctx)
{
some_thread * ctx = (some_thread *) somethread_ctx;
// Do actual thing
}
pthread_t i;
};

int main (void)
{
pizza_list pz = new_pizza_list();
some_thread first_cook(pz);
some_thread second_cook(pz);
first_cook.start_thead();
second_cook.start_thead();
}

现在这解决了您的问题,因为您可以简单地从主线程初始化抽象披萨列表,通过共享内存(将在构造函数中传递(访问您的 cook-thread,并同时运行它们,我必须强调,在这种情况下somethread_main函数表示您的 cook 线程的主要, 应该是线程安全的,由您使用互斥体安全地访问每个线程中的pizza_list。

另外,我已经编写了代码而没有编译它,所以它现在可以编译,但概念本身应该对您有所帮助,

编辑:如评论中所述,您绝对可以使用std::thread而不是pthread_create,这只是将指针this传递给某个函数并将该函数用作线程入口点的概念,从而允许您访问其数据成员