【问题标题】:How to make this code works as asynchronous program如何使此代码作为异步程序工作
【发布时间】:2019-09-19 22:49:54
【问题描述】:

今天我将实现一个非常基本的 Thread 类。我的问题是为什么这段代码会同步运行:

struct Clerk : public Thread
{
    Clerk()
    {
        IsOnService = false;
    }
    void Run()
    {
        std::deque<int> dq;
        std::cout << this->GetId() << " receive new customer " << '\n';
        for (int i = 0; i < 1000000; ++i) dq.push_front(i);
        std::cout << this->GetId() << " has finished" << '\n';

        IsOnService = false;
    }

    bool IsOnService;
};

struct Customer
{
    bool IsOnService;
};

struct Service
{
    Clerk*      clerk;
    Customer*   customer;
    Service(Clerk* c, Customer* cu)
    {
        clerk = c;
        customer = cu;
        clerk->Join();
    }
};

int main()
{
    int nClerks = 5;
    Clerk* clerks[] = { 
        new Clerk(), new Clerk(), new Clerk(), new Clerk(), new Clerk()
    };

    while (1) {
        if (GetAsyncKeyState(0x43) & 0x7FFF) {
            Customer* newCustomer = new Customer();
            for (int i = 0; i < nClerks; ++i)
                if (!clerks[i]->IsOnService) {
                    Service* newService = new Service(clerks[i], newCustomer);
                    delete newService;
                    break;
                }
        }
    }
    for (int i = 0; i < nClerks; ++i) delete clerks[i];
    return 0;
}

首先

双端队列仅用于进行需要花费数次的艰苦工作,但是当我运行上面的代码时,它需要时间,但是每个线程运行线程我的意思是当我运行它时我有这样的事情:

C:&gt;100 receive new customer

...几次...

C:&gt;100 has finished

C:&gt;150 receive new customer

...几次...

C:&gt;150 has finished

...等等

我希望拥有的行为如下:

C:&gt;100 receive new customer

C:&gt;150 receive new customer

C:&gt;100 has finished

C:&gt;150 has finished

或者类似的东西。如果有人可以帮助我。我使用 deque 是因为我想做一个需要时间的任务,但代码需要在 C++98 中编译。请不要用 C++11 或更高版本实现的代码回答我。

【问题讨论】:

  • 无关:C++03 从未得到任何尊重。
  • 不相关:保存一些动态分配并将Clerk* clerks[] = { new Clerk(), new Clerk(), new Clerk(), new Clerk(), new Clerk()}; 替换为Clerk clerks[5];Service* newService = new Service(clerks[i], newCustomer); delete newService;Service newService(&amp;clerks[i], newCustomer); 记住C++ 不是一种野蛮的语言,你必须new 一切。跨度>
  • 如果没有看到应该使事情并行运行的代码,很难弄清楚为什么代码会同步运行。您应该提供一个 minimal reproducible example 来证明该问题。特别是,您的自定义 Thread 类是什么样的?正在调用的Join 函数是什么?
  • @JaMiT 当提问者几个小时前询问Thread class 时,我对这个确切的错误发表了评论。

标签: c++ winapi c++98


【解决方案1】:

每次您将工作添加到Clerk

Service(Clerk* c, Customer* cu)
{
    clerk = c;
    customer = cu;
    clerk->Join();
}

从提问者的previous question 中提升Join 函数

void Thread::Join()
{
    m_handle = (HANDLE)_beginthreadex(0, 0, &this->call, 0, 0, 0);
    if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}

我们可以看到调用线程停止死亡并等待Clerk的线程完成。换句话说,主线程停止,Clerk 线程运行完成,然后主线程恢复并将下一个作业排队到下一个Clerk。没有两个Clerks 会同时处于活动状态。

您需要将作业添加到Clerks 并让Clerks 运行每个Clerk 一个且只有一个线程。当没有更多工作要添加时,您可以加入Clerks。这需要对上一个问题中的 Thread 类进行相当大的重写。

你真正想要的是让自己成为thread pool of Clerks。

顺便说一下,重新考虑Service。这里不需要上课。由于 Service 是创建后立即销毁的,并且在它处于活动状态时实际上不需要维护任何状态,所以 free function 就足够了。

【讨论】:

  • 我们实际上并不知道 Join 的作用。
  • 我该怎么做?你能给我一个基本的例子吗?谢谢
  • 也许你可以在github或codeproject中搜索一些例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
相关资源
最近更新 更多