我有一个我个人实现的数据结构,现在需要跨多个线程使用。
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
并不是问题,因为它们都是访问者。但是,get
和print
在当前正在调用add
时无效。反之亦然,如果add
和get
当前正在进行中,则print
无效。
所以我将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;
}
但,我认为这种方法存在很多问题,我找不到解决问题的方法:
myStruct
完成使用的第一种方法不一定是接下来的方法。accessors
计数器从0
更改为1
(意味着他们想要开始阅读),这可能是一个mutator线程看到它的值是0
并开始变异。然后,mutator线程和访问者线程将同时进行。while
循环中之外,我不知道如何使某些线程在需要执行此任务时正常睡眠和唤醒。答案 0 :(得分:0)
你有正确的想法,只是错误的方法。我不确定您正在编程的操作系统,但是您想要查看mutex
或semaphore
的概念来执行您想要执行的操作。
在兼容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
循环是一个坏主意。在这种情况下,您正在使用所谓的繁忙循环。在这里阅读更多内容:
使用mutex
或semaphore
,不需要while循环。祝你好运!