C - 如何使数据结构实现同步?



我有一个我个人实现的数据结构,现在需要跨多个线程使用。

typedef struct 
{
void** array_of_elements;
size_t size;
} myStruct;

为简单起见,假设我的数据结构具有以下函数:

// Gets a data element from the structure.
void* get(myStruct *x);
// Prints out all the data elements.
void print(myStruct *x);
// Adds an element into the structure.
void add(myStruct *x, void *to_be_added);

当另一个线程调用get时调用print没有任何问题,因为它们都是访问器。但是,当前调用add时,getprint无法正常工作。反之亦然,如果当前正在进行getprint,则add不起作用。

所以我myStruct更改为如下所示:

typedef struct 
{
void** array_of_elements;
size_t size;
// True when a mutator is editing this struct.
bool mutating;
// The number of threads currently accessing this struct.
int accessors;
} myStruct;

现在我的函数如下所示:

void* get(myStruct *x)
{
// Wait for mutating to end.
while (x->mutating);
// Indicate that another accessor is now using this struct.
x->accessors++;
// get algorithm goes here
// Declare we are finished reading.
x->accessors--;
return ...
}
// Same as above...
void print(myStruct *x)
...
void add(myStruct *x)
{
// Wait for any accessors or mutators to finish.
while (x->mutating || x->accessors > 0);    
x->mutating = true;
// add algorithm here
x->mutating = false;
}

但是,我认为这种方法有很多问题,我找不到解决它们的方法:

  • 我的一位同学告诉我,使用 while 循环会极大地减慢线程的速度。
  • 它没有队列的感觉。开始等待myStruct完成使用的第一种方法不一定是下一个方法。
  • 即使我有一个队列数据结构,下一个线程,该数据结构也需要同步,这本身就是一个需要同步数据结构来同步自身的无限循环
  • 我认为有可能在同一个纳秒内,一个线程将accessors计数器从0更改为1(这意味着他们想要开始读取),突变线程可能会看到它的值是0并开始变异。然后,突变器线程和访问器线程将同时运行。
  • 我很确定这种逻辑会导致堵塞(线程无限等待)。
  • 我不知道如何让某些线程在需要执行此任务时休眠和唤醒,除了让它卡在while循环中。

你有正确的想法,只是错误的方法。 我不确定你在什么操作系统上编程,但你想看看mutexsemaphore的概念来做你想做的事情。

在符合 POSIX 标准的 Linux/Unix 上,您可以查看 pthreads:

http://www.cs.wm.edu/wmpthreads.html

在 Windows 上,您可以查看Critical Sections,寻找接近mutex概念的内容:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms682530(v=vs.85).aspx

或者WaitForMultipleObjects接近semaphore的东西:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx

而且,是的,使用while循环是一个坏主意。 在本例中,您使用的是所谓的繁忙循环。 更多阅读在这里:

什么是繁忙循环?

使用mutexsemaphore,不需要 while 循环。 祝你好运!

最新更新