簡體   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