开发者

Sharing a struct safely amongst multiple threads

Under Windows/C++, if I have a struct:

struct ListItem {
    ListItem* next;
    ListItem* prev;
    ...
}

together with multiple threads running in both the main process and in several dynamically loaded DLLs, and all of those threads need to share the above struct, how do I stop them stomp开发者_运维技巧ing on each other? Something like:

ListItem* list = ...

A

list->next = ...

B

What do I put at A and B to prevent no more than one thread at a time running list->next = ...?


There are two main ways. One, possibly the simplest, is to simply send each thread it's own copy of the data structure. This way you won't have to use synchronization to protect the data, since no thread shares another thread's data.

But that won't work in a lot of situations. Sometimes you really do need to share a common data structure. In which case, you need to protect the data structure with some form of synchronization object. Boost.Threads provides some cross-platform ones, and I'm sure someone will show you how to use them. Since you asked specifically about Windows, I'll show you a Windows way.

You can use a CRITICAL_SECTION. First, you need to initialize the critical section in your main thread, before you kick off your worker threads:

int main()
{
// ...
  CRITICAL_SECTION cs;
  InitializeCriticalSection(&cs);
// ...
}

Then pass the pointer to the cs to each worker thread. (This is left as an excercise.) In each worker thread, enter the cs before working with your data, and leave it when you're done.

CRITICAL_SECTION* pcs = ...; // passed in from main thread
EnterCriticalSection(pcs); // this will block until the cs is "available"
list->next = ...
LeaveCriticalSection(pcs); // makes the cs available to other threads

The above is psudocode, and has much room for improvement. For example, the critical section should be wrapped in an RAII object so it is automatically destroyed when you're done with it. Similarly, the locking and unlocking should also be done in an RAII object so that it is always unlocked no matter how you exit your thread function, even in the face of exceptions.

You should note that a CRITICAL_SECTION can only be used by a single process. If you need to use a mutex-type object across multiple processes (not what you seem to need here), then you need to use a named mutex instead.


Use Windows Mutex objects where you have multiple processes that may access one resource.

If your threads are all on one process then you can use EnterCriticalSection / LeaveCriticalSection.


You are looking for synchronization. Take a look at mutex.

http://www.relisoft.com/win32/active.html

http://msdn.microsoft.com/en-us/library/ms684266(v=vs.85).aspx

http://www.installsetupconfig.com/win32programming/threadprocesssynchronizationapis11_42.html


Depending on what you need the structure for, you can use some lockless data structure, like Win API interlocked SList. This way even when multiple threads are performing operations, the data structure is still consistent.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜