[英]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.