Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将抽象对象从主线程发送到其他线程_C++_Multithreading - Fatal编程技术网

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

C++ 将抽象对象从主线程发送到其他线程,c++,multithreading,C++,Multithreading,我正在做一个比萨店餐厅模拟,其中的主线程是前台,它可以接受订单并在抽象的比萨对象APizza中进行转换,在这个前台我有一个厨房对象,其中包含一个由线程表示的厨师列表(std::list\u cooks)我想把这些抽象的比萨饼从接待主线程传递给我的子线程厨师,我想让他们能够从厨房主线程的配料库(stock*_配料)中挑选,我知道我必须使用互斥锁来锁定配料库存变量,然后再修改它,这样许多厨师就不会在访问和更改库存数据的同时做出不可预测的行为 我正在寻找一些方法来传递这些比萨饼,并使我的主食厨房配料库

我正在做一个比萨店餐厅模拟,其中的主线程是前台,它可以接受订单并在抽象的比萨对象APizza中进行转换,在这个前台我有一个厨房对象,其中包含一个由线程表示的厨师列表(std::list\u cooks)我想把这些抽象的比萨饼从接待主线程传递给我的子线程厨师,我想让他们能够从厨房主线程的配料库(stock*_配料)中挑选,我知道我必须使用互斥锁来锁定配料库存变量,然后再修改它,这样许多厨师就不会在访问和更改库存数据的同时做出不可预测的行为

我正在寻找一些方法来传递这些比萨饼,并使我的主食厨房配料库存(库存*_配料)库存可以从厨师那里获得

以下是我的架构:


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 Shell();
APizza*制作订单(PizzaType、PizzaSize);
空厨房();
私人:
int parseCommands();
标准::地图(厨房清单);
受保护的:
double _乘数;//烹饪时间乘数。
厨师人数;//每个厨房的厨师人数。
大小\u t\u重新进货;//重新进货配料的时间(毫秒)。
};
班级厨房
{
公众:
厨房(双人床,t码,t码);
~Kitchen();
APizza*制作订单(PizzaType、PizzaSize);
无效状态();
作废派送披萨(阿皮萨*披萨);
bool已满();
私人:
std::stack\
_比萨饼;
标准:列出厨师;
原料;
double _乘数;//烹饪时间乘数。
大小\u t\u ncooks;//每个厨房的厨师人数。
大小\u t\u重新进货;//重新进货配料的时间(毫秒)。
雪的大小;
//管道(u管),;
};
班主任
{
公众:
库克(双倍乘数);
~Cook();
无效运行();
boolcancook();
void cookPizza(APizza);;
私人:
阿皮萨咖喱比萨;
bool_是cooking;
双乘数;
};
这是我要传递比萨饼的地方

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;       
  }
int接收::Shell()
{
std::string命令;
标准::cout>kitch*kitch=新厨房(\u乘数,\u厨师,\u重新进货);
而(1)
{
getline(标准::cin,命令);
如果(!command.compare(“exit”)|| std::cin.eof())
返回(0);
其他的
{
orders=splitStr(命令“;”);
}
如果(!orders.empty())
{
for(const std::string&order:orders)
{
尺寸nPizza=getPizzaNbr(订单);
PizzaType tPizza=getPizzaType(订单);
Pizzazize sPizza=GetPizzazize(订单);
如果(nPizza==0 | | tPizza==(PizzaType)0 | | sPizza==(PizzaSize)0){

STD::CUT< P>老实说,跳过代码,C++中有一个众所周知的技巧,其中创建了一个封装了<代码> pTox的类,并传递了自指针(<代码>此< /代码>)对于一个新线程,我将添加一些引用,我通常会推荐,创建一个普通工人抽象类,而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线程同时运行它们,我必须强调,
somethread\u main
函数在本文中表示cook线程的主线程,应该是线程安全的,并且由您使用互斥锁安全地访问每个线程中的pizza\u列表

另外,我在编写代码时没有编译它,因此它现在可能会编译,但是这个概念本身应该可以帮助您

编辑:
正如评论中提到的,您可以明确地使用STD::ToeType代替PthRead创建,这只是一个传递代码< > < /Cult>指针的函数,并使用该函数作为线程入口点,从而允许您诚实地访问其数据成员

,只是跳过代码,在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线程同时运行它们,我必须强调,
somethread\u main
函数在本文中表示cook线程的主线程,应该是线程安全的,并且由您使用互斥锁安全地访问每个线程中的pizza\u列表

另外,我在编写代码时没有编译它,因此它现在可能会编译,但是这个概念本身应该可以帮助您

编辑:
正如在评论中提到的,您完全可以使用std::thread而不是pthread_create,这只是将
这个
指针传递到某个函数,并使用该函数作为线程入口点,从而允许您访问其数据成员的一个概念,看起来您拥有了所有正确的部分,那么您尝试了什么呢?注意:与man不同Y语言,C++中不必<代码>新< /代码>所有对象…<代码>厨房