Jump to content
  • Advertisement
Sign in to follow this  
Spearhawk

Accessing a vector in different threads

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

If you intended to correct an error in the post then please contact us.

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:
	
	void AddEvent(s32 index, u32 subcode);

private:

	std::vector<Event> m_aEvent;
};

void TranslationManager::AddEvent(s32 index, u32 subcode)
{
	ERRORCODE res = 0;

	// Update event
	m_aEvent[index].subcode = subcode;
	m_pEventManager->AddEvent(m_aEvent[index],res);
}


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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!