我有一个跨平台的c ++程序,我正在使用boost库来创建一个异步计时器.
我有一个全局变量:
bool receivedInput = false;
Run Code Online (Sandbox Code Playgroud)
一个线程等待并处理输入
string argStr;
while (1)
{
getline(cin, argStr);
processArguments(argStr);
receivedInput = true;
}
Run Code Online (Sandbox Code Playgroud)
另一个线程运行一个计时器,每10秒调用一次回调.在该回调中,我检查是否收到了消息
if (receivedInput)
{
//set up timer to fire again in 10 seconds
receivedInput = false;
}
else
exit(1);
Run Code Online (Sandbox Code Playgroud)
这样安全吗?对于线程2中的读取,我认为无关紧要,因为条件将评估为true或false.但我不确定如果两个线程同时尝试设置receivedInput会发生什么.我也把我的计时器比我期望接收输入的时间长3倍,所以我不担心比赛情况.
编辑:为了解决这个问题,我在读取receivedInput时设置了receiveInput和boost :: shared_lock时使用了boost :: unique_lock.我在这里用了一个例子
我们已经实现了读写锁
typedef boost::unique_lock<boost::shared_mutex> WriterLock;
typedef boost::shared_lock<boost::shared_mutex> ReadersLock;
Run Code Online (Sandbox Code Playgroud)
我们有许多多线程读取器,但只有少数写入器。读者与其他读者共享访问权限,但阻止作者。Writer 会阻塞,直到它拥有对资源的独占访问权。
我们在 boost 文档中找不到这个...防止 Writer 饥饿的策略是什么?
例如,如果有许多读者都从线程池中获取锁,那么在写入者最终获取锁之前,是否有保证尝试锁的次数上限?
我们看到的性能数据似乎表明写入必须等到完全没有读取器为止,并且在极少数情况下会等待很长时间,因为新读取器可以在当前读取器得到服务时请求锁定。在这种情况下,在我们的代码中,编写者似乎必须等待很长时间,直到根本没有读取。
我们更喜欢一个更像队列的系统,当写入者请求锁定时,所有当前的读取者都会耗尽,但所有新传入的读取者都会阻塞在写入者请求之后。
Boost 中可升级锁概念的行为是什么? 提升线程数
它没有说明它如何处理作家饥饿问题。
堆栈溢出有几个例子,其中一个函数获得的升级锁第一和然后获得由升级的独占访问.我的理解是,如果不小心使用,这会导致死锁,因为两个线程都可以获得可升级/共享锁,然后两者都尝试升级,此时两者都不能继续,因为另一个具有共享锁.
我想要的是首先获得独占锁,然后降级到共享锁,而不完全释放锁.我找不到这样的例子.有任何想法吗?
让我们考虑一下C++中的这样一个类:
class CuteClass
{
public:
int getFancyInt() const;
float getNiceFloat() const;
string getPerfectString() const;
void setIntSomething(int something);
void setInternalState(State newState);
};
Run Code Online (Sandbox Code Playgroud)
可以从几个不同的线程同时访问此类的实例.然后:
所有getMethods(getFancyInt,getNiceFloat,getPerfectString)都不应该相互阻塞.它们不会更改对象的内部状态.
所有setMethod(setIntSomething,setInternalState)都应该:
带有互斥锁的简单lock_guard将满足除一个之外的所有要求 - getMethod将阻止其他getMethods.
在这种情况下,什么解决方案容易和干净?
我只是想用100多个upvotes来实现有关互斥的答案。我所做的就是复制粘贴代码,以便我的班级像这样读取(简化):
mymutexclass.hclass MyMutexClass {
public:
void write( uint32_t id, const std::string &str );
std::string read( uint32_t id ) const;
private:
boost::shared_mutex _access;
std::map<uint32_t, std::string> strings;
};
Run Code Online (Sandbox Code Playgroud)
mymutexclass.cppvoid MyMutexClass::write( uint32_t id, const std::string &str ) {
boost::unique_lock< boost::shared_mutex > lock(_access);
strings[id] = name;
}
std::string MyMutexClass::read( const uint32_t id ) const {
boost::shared_lock< boost::shared_mutex > lock(_access); // ERROR HERE
if( strings.count( id )>0)
return strings.at(id);
else
return "No value.";
}
Run Code Online (Sandbox Code Playgroud)
而且我得到一个错误,仅针对读取的互斥行:
error C2664: …Run Code Online (Sandbox Code Playgroud) 看来,这个问题被 问 频繁,但我不来任何明确的结论.当我有以下情况时,我需要一些帮助来确定我是否应该(或必须!)在访问/修改全局变量时实现锁定代码:
所以问题是,我应该使用互斥锁来锁定对全局变量的访问吗?
更具体地说,我正在编写一个C++库,它使用网络摄像头来跟踪纸张上的对象 - 计算机视觉是CPU密集型的,因此性能至关重要.我有一个单一的,其是在剥离工作线程Open()功能.该线程处理所有对象跟踪.Close()调用函数时,它会终止(间接w /全局标志).
感觉就像我只是要求内存损坏,但我没有观察到死锁问题,也没有遇到从这些访问器函数返回的任何错误值.而几个小时的研究后,一般人印象中我得到的是,"咩,可能随便啦.有乐趣的是." 如果我确实应该使用互斥锁,为什么我没有遇到任何问题呢?
这是对我当前程序的过度简化:
// *********** lib.h ***********
// Structure definitions
struct Pointer
{
int x, y;
};
// more...
// API functions
Pointer GetPointer();
void Start();
void Stop();
// more...
Run Code Online (Sandbox Code Playgroud)
实现看起来像这样......
// *********** lib.cpp ***********
// Globals
Pointer p1;
bool isRunning = false;
HANDLE hWorkerThread;
// more...
// API functions
Pointer GetPointer()
{
// NOTE: my current implementation is …Run Code Online (Sandbox Code Playgroud) c++ ×6
boost ×2
c++11 ×2
mutex ×2
boost-asio ×1
boost-mutex ×1
boost-thread ×1
concurrency ×1
opencv ×1
timer ×1