我有一個我個人實現的數據結構,現在需要跨多個線程使用。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