-2

Today I'd implement a very basic Thread class. My question is why this code run synchronously:

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;
}

First

The deque is only for make a hard work that takes several time, but when I run the code above it takes time but run thread per thread I mean I have something like this when I run it:

C:>100 receive new customer

... several time ...

C:>100 has finished

C:>150 receive new customer

... several time ...

C:>150 has finished

... and so on

And the behavior that I wish to have is the following:

C:>100 receive new customer

C:>150 receive new customer

C:>100 has finished

C:>150 has finished

Or something like that. If someone can help me. I'd used deque because I want to make a task that takes time but the code needs to compile in C++98. Plz don't answer me with code that is implemented in C++11 or higher.

  • Unrelated: C++03 never gets any respect. – user4581301 Sep 19 '19 at 23:05
  • 1
    Unrelated: Save some dynamic allocation and replace `Clerk* clerks[] = { new Clerk(), new Clerk(), new Clerk(), new Clerk(), new Clerk()};` with `Clerk clerks[5];`and `Service* newService = new Service(clerks[i], newCustomer); delete newService;` with `Service newService(&clerks[i], newCustomer);` Remember C++ isn't some barbaric language where you have to `new` everything. – user4581301 Sep 19 '19 at 23:09
  • It's rather difficult to figure out why code runs synchronously without seeing the code that is supposed to make things run in parallel. You should give a [mcve] that demonstrates the issue. In particular, what does your custom `Thread` class look like? What is the `Join` function that is being called? – JaMiT Sep 19 '19 at 23:51
  • @JaMiT I have the advantage having commented on this exact bug when the asker asked about the [Thread class](https://stackoverflow.com/questions/58018730/how-to-deal-with-multiple-parameters-of-different-types-in-c98) a few hours earlier. – user4581301 Sep 20 '19 at 00:14

1 Answers1

0

Every time you add a job to a Clerk with

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

Lifting the Join function from the Asker's previous question

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

we can see that the calling thread stops dead and waits for the Clerk's thread to complete. In other words, main thread stops, Clerk thread runs to completion and then main thread resumes and queues the next job to the next Clerk. No two Clerks are ever active at the same time.

You need to add jobs to the Clerks and let the Clerks run with one, and only one, thread per Clerk. When there are no more jobs to be added, then you join on the Clerks. This requires a fairly big re-write of the Thread class from the previous question.

What you really want here is to make yourself a thread pool of Clerks.

Rethink Service, by the way. There's no need for a class here. Since Service is created, is destroyed immediately after, and doesn't really need to maintain any state while it is alive, a free function will be sufficient.

user4581301
  • 33,082
  • 7
  • 33
  • 54