从单个工作线程更新全局变量:我需要互斥锁吗?

Cou*_*sen 0 c++ multithreading opencv mutex

看来,这个问题 频繁,但我不来任何明确的结论.当我有以下情况时,我需要一些帮助来确定我是否应该(或必须!)在访问/修改全局变量时实现锁定代码:

  • 在文件范围定义的全局变量
  • 一个"工人"线程读/写全局变量
  • 从主进程线程调用调用访问器函数返回这些全局变量

所以问题是,我应该使用互斥锁来锁定对全局变量的访问吗?

更具体地说,我正在编写一个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 actually returning a pointer to the
  // global object in memory, not a copy of it, like below...

  // Return copy of pointer data
  return p1;
}

// more "getters"...

void Open()
{
  // Create worker thread -- continues until Close() is called by API user
  hWorkerThread = CreateThread(NULL, 0, DoWork, NULL, 0, NULL);
}

void Close()
{
  isRunning = false;

  // Wait for the thread to close nicely or else you WILL get nasty
  // deadlock issues on close
  WaitForSingleObject(hWorkerThread, INFINITE);
}

DWORD WINAPI DoWork(LPVOID lpParam)
{
  while (isRunning)
  {
    // do work, including updating 'p1' about 10 times per sec
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

最后,从外部可执行文件调用此代码.像这样的东西(伪代码):

// *********** main.cpp ***********
int main()
{
  Open();

  while ( <esc not pressed> )
  {
    Pointer p = GetPointer();
    <wait 50ms or so>
  }
  Close();
}
Run Code Online (Sandbox Code Playgroud)

我应该采取不同的方法吗?这个没有问题的问题让我疯狂: - /我需要确保这个库稳定并返回准确的值.任何见解将不胜感激.

谢谢

Mar*_*ork 5

如果只有一个线程访问一个对象(读取和写入),则不需要锁定.

如果只读取对象,则不需要锁定.(假设您可以保证在构造期间只有一个线程访问该对象).

如果任何线程写入(更改状态)对象.如果有其他线程访问该对象,则必须锁定所有访问(读取和写入).虽然您可以使用允许多个读取器的读锁定.但是写操作必须是独占的,没有读者可以在状态被更改时访问该对象.