私は私が個人的に実装したデータ構造を持っています。これは現在、複数のスレッドにわたって使用する必要があります。簡単にするために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);
彼らは両方のアクセサであるため、別のスレッドがprint
を呼び出している間、それはget
を呼び出すために全く問題はありません。ただし、add
が現在呼び出されている間は、get
とprint
は機能しません。逆の場合、は、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
の使用が完了するのを待っている最初の方法は、必ずしも次に進む方法ではありません。 - スレッドが次に進むキューデータ構造があったとしても、データ構造も同期させる必要があるそれ自体は、同期データ構造を必要とする無限ループであるです。
- 私はそれは同じナノ秒に1つのスレッドが(彼らは読書を開始したいという意味)
0
から1
にaccessors
カウンタを変更し、それが0
で、変異開始値です見にミューテータスレッドのために可能だということも可能だと思います。次に、ミューテータスレッドとアクセサスレッドの両方が同時に実行されます。 - 私はこのロジックがグリッドロック(互いに無限に待っているスレッド)を引き起こす可能性があると確信しています。
- 私は特定のスレッドを覚醒させる方法を知らず、
while
ループに詰め込まれているだけでなく、このタスクに必要なときに目を覚まします。
読み書きロックを調べてみてください... – Dmitri
@Dmitri私は実際の実装がどのように見えるのかを遠隔で読み書きするためのロックを持っていませんか? – Hatefiend
スレッド間で変数を共有する場合は、アトミックアクセスやmutexのような何らかの同期メカニズムを使用する必要があります。読取り/書込みロックは、複数のスレッドで読取りを許可するが、書込みには排他アクセスを必要とすることを除いて、mutexと似ています。 posixスレッドの場合、 'pthread_rwlock_t'があり、ウィンドウには"スリムなリーダーライターロック "があります。 – Dmitri