Accessing a vector in different threads

This topic is 3657 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi, As I understand it the vector class isn't thread safe. However I'm wondering if it would be thread safe to just access different parts of the same vector from different threads. Would something like this work?
struct Event
{
STRING text;
s32 type;
u32 subcode;
};

class TranslationManager
{
public:

private:

std::vector<Event> m_aEvent;
};

{
ERRORCODE res = 0;

// Update event
m_aEvent[index].subcode = subcode;
}


This acts like an interface to another developing environment (CoDeSys) and can be called from several different threads. Assume that m_pEventManager->AddEvent(Event &ev) is thread safe, that I can guarantee that index will never be the same in two different threads and that the vector will not have elements added or removed. I'm using VS.NET 2005 if that makes any difference. Thanks in advance Leon Ljunggren Edit: Fixed the tittle

Share on other sites
So long as you don't call any non-const operations on the vector while both threads are going to be accessing it, you should be ok. But why not just add and remove elements from the various threads, and mutex lock it?

Share on other sites
There is no partial thread-safety. It's an all or nothing thing.

First, why are you using a vector? In your case it *needs* to be fixed - use regular fixed-size array. Anything and everything vector offers is redundant at best, and code breaking at worst. (see also boost::array).

Thread-safety is achieved by eliminating race conditions. There's several approaches, from critical sections, to lock-less algorithms, down to - shared-nothing model.

The later one is of particular interest to you since you say "to just access different parts of the same vector from different threads".

As long as there is no overlap, the contents of each vector will always be handled by their own thread independently, and there will be no contention. Also - data that is not modified (during life-time of any thread accessing it) is considered immutable and may be shared between threads without any problems.

Unfortunately, your example doesn't say anything about threads or how they'll be accessing this data, so it's impossible to say if it would work or not.

Share on other sites
You're absolutely right, I don't need the vector. It was a remnant of an old design that had outdated requirements (that events should be executed at specific times). I've removed it and instead let the threads add events directly using AddEvent() in the translation manager.
It's still a "lock" design of course since I perform locking once I add the events to a queue for later processing.

void TranslationManager::AddEvent(char* text, u32 type, u32 subcode){	Event ev;	ev.text = CharToWide(text);	ev.type = type;	ev.subcode = subcode;		// Add event	m_pEventManager->AddEvent(ev);}void EventMgr::AddEvent(Event &event){  m_eventQueue.Add(event);}template <class T, u32 N>void Queue<T, N>::Add(T item){  EnterCriticalSection(&m_criticalSection);    *m_pWritePointer = item;    m_pWritePointer++;    m_items++;    m_itemsUnprocessed++;    // If write pointer is outside buffer, set back to beginning of buffer    if(m_pWritePointer == (m_Queue + N))    {      m_pWritePointer = m_Queue;    }  LeaveCriticalSection(&m_criticalSection);}

The threads are run in CoDeSys (a SoftPLC) and perform diagnostic with different priorities that can generate events. These events are added to a queue using the AddEvent() function of the translation manger (wrapped in a c-call) and then another thread will execute the events (writing to a database) when there's time, letting the higher priority diagnostic run as it needs.