我如何使用互斥锁来解决此问题在c ++

时间:2018-12-05 21:51:17

标签: multithreading

我是我自己一个人学习多线程的新手,发现这个问题时没有任何解决方法。这段代码模拟了4个球手围成一圈传球,每个球手都是一个线程,他们的位置应该是0、90、180、270度,但是这段代码的运行结果是随机的+/- 5。 ();处于许多不同的位置,然后在线执行一些互斥指令,但仍然无法正常工作。

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;

const int numPlayers    = 4;
const int radius        = 100;

class CPlayer
{
public:
    int id;
    bool done;
    double pos;
    bool hasTheBall;
    CPlayer(int playerNum) { id = playerNum; };
    ~CPlayer() {};
};

CPlayer *players[numPlayers];
bool keepGoing;
double ballPos;

void Sleep(long sleepTime)
{
    std::chrono::milliseconds timespan(sleepTime);
    std::this_thread::sleep_for(timespan);
}

void WaitForKey(void *data)
{
    (void)::getchar();
    keepGoing = false;
}

void Player(void *data)
{
    CPlayer *player = (CPlayer *)data;
    double x = (double)radius * cos(player->pos * M_PI / 180.0);
    double y = (double)radius * sin(player->pos * M_PI / 180.0);
    printf("Player %d starting at (%f,%f)...\n", player->id, x, y);
    mtx.lock();
    while (keepGoing)
    {
        if (abs(ballPos - player->pos) < 1e-3)
        {
            player->hasTheBall = true;
            printf("Starting animation for player %d (theta=%f)...\n", player->id, ballPos);
            Sleep(2000);
            printf("Ending animation for player %d...\n", player->id);
            player->hasTheBall = false;
        }
    }
    mtx.unlock();
    printf("Player %d ended.\n", player->id);
    player->done = true;
}

int main(int argc, char *argv[])
{
    keepGoing = true;
    int p;
    ballPos = 0;
    for (p=0; p<numPlayers; p++)
    {
        players[p] = new CPlayer(p);
        players[p]->done = false;
        players[p]->pos = ballPos;
        players[p]->hasTheBall = false;
        ballPos += 360.0 / numPlayers;
    }

    std::thread *inputThread = new std::thread(WaitForKey, nullptr);
    std::thread *playerThreads[numPlayers];
    for (p=0; p<numPlayers; p++)
        playerThreads[p] = new std::thread(Player, (void *)players[p]);

    bool finished, moveBall;
    ballPos = 0;
    do
    {
        finished = true;
        moveBall = true;
        for (p=0; p<numPlayers; p++)
        {
            if (!players[p]->done)
                finished = false;
            if (players[p]->hasTheBall)
                moveBall = false;
        }
        if (moveBall)
        {
            ballPos++;
            if (ballPos > 360)
                ballPos = 0;
        }
    } while (!finished);

    for (p=0; p<numPlayers; p++)
    {
        playerThreads[p]->join();
        delete playerThreads[p];
        delete players[p];
    }
    inputThread->join();

    return 0;
}

有人可以帮我弄清楚如何从4个不同的线程中锁定变量吗?谢谢!

0 个答案:

没有答案