簡體   English   中英

boost :: scoped_lock不能使用本地靜態變量?

[英]boost::scoped_lock not working with local static variable?

我制作了以下示例程序來使用boost線程:

#pragma once
#include "boost\thread\mutex.hpp"
#include <iostream>

class ThreadWorker
{
public:
    ThreadWorker() {}
    virtual ~ThreadWorker() {}

    static void FirstCount(int threadId)
    {
        boost::mutex::scoped_lock(mutex_);
        static int i = 0;

        for(i = 1; i <= 30; i++)
        {
            std::cout << i << ": Hi from thread:  " << threadId << std::endl;
        }

    }

private:
    boost::mutex mutex_;
};

主要課程:

// ThreadTest.cpp
#include "stdafx.h"
#include "boost\thread\thread.hpp"
#include "ThreadWorker.h"

int _tmain(int argc, _TCHAR* argv[])
{
    boost::thread thread1(&ThreadWorker::FirstCount, 1);
    boost::thread thread2(&ThreadWorker::FirstCount, 2);
    boost::thread thread3(&ThreadWorker::FirstCount, 3);

    thread1.join();
    thread2.join();
    thread3.join();

    std::string input;
    std::cout << "Press <enter> to finish...\n";
    std::getline( std::cin, input );
    return 0;
}

當我運行它時,我得到以下輸出:

1: Hi from thread:  1
1: Hi from thread:  3
2: Hi from thread:  3
...

看起來線程1首先到達那里然后是線程3.是不是scoped_lock應該阻止其他線程進入該部分代碼? 運行FirstCount()的第一個線程不應該完成嗎?

UPDATE

我認為我的代碼有一點是錯誤的:

boost::mutex::scoped_lock(mutex_);

我認為應該是這樣的:

boost::mutex::scoped_lock xyz(mutex_);

一旦我這樣做,它確實使關於mutex_的抱怨不是靜態的。 為什么它首先起作用我不確定。 將mutex_更改為static會給我一個鏈接錯誤:

1> ThreadWorker.obj:錯誤LNK2001:未解析的外部符號“private:static class boost :: mutex ThreadWorker :: mutex_”(?mutex_ @ ThreadWorker @@ 0Vmutex @ boost @@ A)1> c:\\ something \\ ThreadTest \\ Debug \\ ThreadTest.exe:致命錯誤LNK1120:1個未解析的外部

還在玩它。

你有兩個錯誤:

首先,正如已經注意到的, mutex_應該是靜態的:

private:
    static boost::mutex mutex_;

當然要在某處聲明它(最好在.cpp文件中!):

boost::mutex ThreadWorker::mutex_{};

現在,為什么編譯器不抱怨? 好吧,因為你實際上沒有在這里用參數mutex_構造一個范圍鎖:

boost::mutex::scoped_lock(mutex_);

其實這不叫你想要的構造,而是創建一個(本地)對象mutex_是類型的scoped_lock ,並通過默認構造函數構造。 因此,沒有編譯器問題。 您應該將其更改為以下內容:

boost::mutex::scoped_lock l{mutex_};

現在編譯器應該開始抱怨mutex_

你有三個獨立的對象,它們都不能看到對方的互斥對象,因為該成員是在每個對象中創建的。

也許你的意思是制作mutex_ static?

編輯:如果我使互斥量靜態並從i變量中刪除靜態,那么它似乎工作,因為我猜你的意思。 似乎是這樣的事情:每個線程立即進入循環,並且由於互斥鎖不是靜態的,因此不會彼此鎖定。 當他們將所有輸出都輸出到控制台時(我不記得在寫入cout時是否存在互斥)並且我得到增量,他們都看到靜態i為30並退出。

編輯2:不,仍然不正確,因為在某些運行中仍然存在散布的值。

編輯3:它編譯的原因是你的scoped_lock是一個臨時的,它似乎讓編譯器拋棄了mutex_應該是靜態的事實。 請嘗試以下代碼:

#include <iostream>
#include "boost\thread\mutex.hpp"
#include "boost\thread\thread.hpp"

class ThreadWorker
{
public:
    ThreadWorker() {}
    virtual ~ThreadWorker() {}

    static void FirstCount(int threadId)
    {
        // Created object f here rather than temprary
        boost::mutex::scoped_lock f(mutex_);
        int i = 0; // Not static

        for(i = 1; i <= 30; i++)
        {
            std::cout << i << ": Hi from thread:  " << threadId << std::endl;
        }

    }

private:
    static boost::mutex mutex_; // Static
};

// Storage for static
boost::mutex ThreadWorker::mutex_;

int main(int argc, char* argv[])
{
    boost::thread thread1(&ThreadWorker::FirstCount, 1);
    boost::thread thread2(&ThreadWorker::FirstCount, 2);
    boost::thread thread3(&ThreadWorker::FirstCount, 3);

    thread1.join();
    thread2.join();
    thread3.join();

    std::string input;
    std::cout << "Press <enter> to finish...\n";
    std::getline( std::cin, input );
    return 0;
}

此代碼是否也使用相同的編譯器進行編譯?

你能看到這段代碼的問題嗎? 嘗試在不編譯的情況下發現問題。

class C {
public:
    static int f () {
        return i;
    }

    int i;
};

int main() {
    return C::f();
}

更新:我剛看了你的更新。

class C {
public:
    static int f () {
        return i;
    }

    static int i;
};

int C::i = whatever;

int main() {
    return C::f();
}

將我的代碼更改為:

ThreadWorker.h:

#pragma once
#include "boost\thread\mutex.hpp"
#include <iostream>

class ThreadWorker
{ 
public:
    ThreadWorker();
    virtual ~ThreadWorker();

    static void FirstCount(int threadId);

private:
    static boost::mutex mutex_;
};

ThreadWorker.cpp:

#include "stdafx.h"
#include "ThreadWorker.h"

boost::mutex ThreadWorker::mutex_;

ThreadWorker::ThreadWorker()
{
}

ThreadWorker::~ThreadWorker()
{
}

void ThreadWorker::FirstCount(int threadId)
{
    boost::mutex::scoped_lock xyz(mutex_);
    static int i = 0;

    for(i = 1; i <= 30; i++)
    {
        std::cout << i << ": Hi from thread:  " << threadId << std::endl;
    }

}

ThreadTest.cpp:

// ThreadTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "boost\thread\thread.hpp"
#include "ThreadWorker.h"

int _tmain(int argc, _TCHAR* argv[])
{
    boost::thread thread1(&ThreadWorker::FirstCount, 1);
    boost::thread thread2(&ThreadWorker::FirstCount, 2);
    boost::thread thread3(&ThreadWorker::FirstCount, 3);

    thread1.join();
    thread2.join();
    thread3.join();

    std::string input;
    std::cout << "Press <enter> to finish...\n";
    std::getline( std::cin, input );
    return 0;
}

我做的更改是1.分隔標題和cpp文件(我最初只是為了使我的帖子更緊湊)2。給scoped_lock變量一個標識符和3.使互斥鎖靜態。

它現在按預期工作,從每個線程順序打印30行。 令我感到困惑的是為什么之前編譯的代碼(因為tinman也能夠編譯我的原始代碼)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM