繁体   English   中英

使用std :: thread的C ++多线程应用程序在Windows上可以正常工作,但在Ubuntu上却不能

[英]C++ multithreaded application using std::thread works fine on Windows but not Ubuntu

我有一个使用C ++ std :: thread库为Ubuntu 14.04和Windows 8.1编写的稍微简单的多线程应用程序。 该代码几乎完全相同,除了我使用操作系统各自的库windows.h和unistd.h来使用Sleep / sleep暂停执行一段时间。 它们实际上都已开始运行,并且Ubuntu版本确实可以保持运行一小段时间,但随后挂起。 因为我知道Windows睡眠需要几毫秒,而Unix睡眠需要几秒钟,所以我在使用sleep / Sleep函数的适当参数。

我已经多次运行该代码,而在Ubuntu上它从未超过两分钟,而我已经两次在Windows上运行了20分钟,然后多次在Windows上运行了大约五分钟,看看我是否很幸运。 这仅仅是与线程库不兼容,还是睡眠不按照我的想法做,还是其他? 那里存在无限循环,因为这是一个学校项目,并且有望在没有死锁或崩溃的情况下运行。

要点是,这是一种经过改进的四向停车,在这种情况下,先到达的汽车不必减速停车。 我们只需要让一辆汽车通过十字路口,这需要3秒钟的时间通过,因此Sleep(3000),而不必担心转弯。 三个线程运行spawnCars函数,还有四个其他线程分别监视N,E,S和W四个方向之一。我希望可以理解为什么我不能发布整个代码,以防其他学生跌倒在此。 除了顶部包含依赖于操作系统的库以外,这两个函数是唯一代码不同的地方。 谢谢。

编辑:由于我刚刚离开并发布了该项目的所有代码,因此如果问题最终陷入僵局,我是否可以要求您只说一句,而不发布深入的解决方案? 我是新来的,因此,如果这与SO的精神背道而驰,请开除,我将尝试解决问题而不阅读详细信息。

        /* function clearIntersection
        Makes a car go through the intersection.  The sleep comes before the removal from the queue
        because my understanding is that the wait condition simulates the go signal for drivers.
        It wouldn't make sense for the sensors to tell a car to go if the intersection isn't yet
        clear even if the lock here would prevent that.
        */
        void clearIntersection(int direction)
        {
            lock->lock();
            Sleep(3000);
            dequeue(direction);
            lock->unlock();
        }
        /* function atFront(int direction)
        Checks whether the car waiting at the intersection from a particular direction
        has permission to pass, meaning it is at the front of the list of ALL waiting cars.
        This is the waiting condition.
        */
        bool isAtFront(int direction)
        {
            lock->lock();
            bool isAtFront = cardinalDirections[direction].front() == list->front();
            lock->unlock();
            return isAtFront;
        }


        void waitInLine()
        {
            unique_lock<mutex> conditionLock(*lock);
            waitForTurn->wait(conditionLock);
            conditionLock.unlock();
        }
        //function broadcast(): Let all waiting threads know they can check whether or not their car can go.
        void broadcast()
        {
            waitForTurn->notify_all();
        }
    };

    /* function monitorDirection(intersectionQueue,int,int)
    Threads will run this function.  There are four threads that run this function
    in total, one for each of the cardinal directions.  The threads check to see
    if the car at the front of the intersectionQueue, which contains the arrival order
    of cars regardless of direction, is the car at the front of the queue for the
    direction the thread is assigned to monitor.  If not, it waits on a condition
    variable until it is the case. It then calls the function to clear the intersection.
    Broadcast is then used on the condition variable so all drivers will check if they
    are allowed to pass, which one will unless there are 0 waiting cars, waiting again if not the case.
    */
    void monitorDirection(intersectionQueue *intersection, int direction, int id)
    {
        while (true) //Do forever to see if crashes can occur.
        {
            //Do nothing if there are no cars coming from this direction.
            //Possibly add more condition_variables for each direction?
            if (!intersection->empty(direction))
            {
                while (!intersection->isAtFront(direction))
                    intersection->waitInLine();
                intersection->clearIntersection(direction);
                cout << "A car has gone " << numberToDirection(direction) << endl;
                //All cars at the intersection will check the signal to see if it's time to go so broadcast is used.
                intersection->broadcast();
            }
        }
    }

罪魁祸首可能是while (!isAtFront(...))循环。 如果在检查和随后的waitInLine()调用之间安排了另一个线程,则队列状态可能会更改,从而导致所有使用者线程最终都处于等待状态。 那时没有线程向您发出condition_variable信号,因此它们将永远等待。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM