我有一个我个人实现的数据结构,现在需要跨多个线程使用。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
因为他们是两个访问的问题。但是,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;
}
但,我觉得有很多的问题,这的方法,我找不到解决方法:
- 我的一位同学告诉我,使用while循环会减慢线程的速度。
- 它没有排队感。开始等待
myStruct
完成使用的第一种方法不一定是接下来的方法。 - 即使如果我有一个队列数据结构的线程去下,数据结构也需要同步,这本身是一个无限循环需要一个同步数据结构来同步自己。
- 我认为可能在相同的纳秒中,一个线程将
accessors
计数器从0
更改为1
(这意味着它们要开始读取),但是可能突变线程看到它的值为0
并开始变异。然后,mutator线程和访问器线程将同时进行。 - 我敢肯定,这个逻辑可能会导致网格锁定(线程无限等待)。
- 我不知道如何使某些线程在需要执行此任务时能够睡眠并唤醒,除了它被卡在
while
循环中。
研究读写锁... – Dmitri
@Dmitri我读写锁的程度如何,甚至不会远远接近实际实现的样子? – Hatefiend
如果你在线程之间共享一个变量,你应该使用原子访问或者像互斥体那样的某种同步机制。读写锁就像一个互斥锁,只是它允许多个线程读取,但需要独占访问才能写入。对于posix线程,有'pthread_rwlock_t',并且windows有“slim reader writer locks” – Dmitri