Archived

This topic is now archived and is closed to further replies.

WebsiteWill

And another thread question

Recommended Posts

Say I have a function like this void threadFunc() { int localInt; int localFloat; //do something with the above //store them in a global variable and computing them globalInt = localInt + globalInt; globalFloat = localFloat + globalFloat; } Now since threads share all common memory, if I have multiple threads using this function then the memory will get mangled because there is no telling exactly what local numbers will get added to the global number and some local numbers can be overwritten before they are used. Using a mutex or a critical section I could lock the entire code but doing so would defeat the purpose of having multiple threads servicing this. Is there any way to create variables local the the thread itself and unique to each thread? So that if I have 4 threads operating on the above function then each of the 4 would have their own local variables. Then I would only need to lock the assignments to the global variables. Obviously this example is trivial and wouldn''t need to be threaded in any way but in RL I have a function that operates on some thread local variables and then does something to a global (sortof) variable. The "global" part is a call to recvfrom and storing the return value on a queue. I''d like the threads to be able to each do their own pre-processing and then only lock the queue when they need to store onto it. However, just locking the queue is causing great havoc as the other local variables are getting abused before they are used. Any way to stop this? Thanks, Webby

Share this post


Link to post
Share on other sites
I can think of a workaround for this.
When I create my threads I am storing their IDs in a vector.

So in the thread function I can get the thread ID and use that to execute multiple locations of the code.

So for the areas where I need to keep variables static to that thread I just wrap them in an
if(threadID = vector[1])
{
//DO THIS CODE
}
else if (threadID = vector[2])
{
//DO THIS CODE
}

Problem is there is then a definite upper limit on the number of threads that I can have without recompiling the code. I''m hoping for a better solution but this will work for now.

Webby

Share this post


Link to post
Share on other sites
NO!

This is EXACTLY the reason why I believe threading is not easy to teach yourself. This is post #6 by you on this subject -- seriously consider buying some sort of book that has an extensive discussion on what threads really are and how to use them, along with examples.

quote:
Obviously this example is trivial and wouldn''t need to be threaded in any way but in RL

There is no guarantee that addition is an atomic operation, so it better be protected.

Each thread has its OWN stack of execution. Your threadFunc() numbers are all allocated on the stack. Threads run within the same process, so they all share the same heap. If you operate on global variables then you have to protect access to those variables.

Yes, there is thread local storage on some platforms. No, you don''t need it.

The workaround is little more than hard-coding a primitive lock. If you only want one thread in a portion of code at the time then use the scoped locking pattern:

{
CriticalSection cs; // acquire the critical section in the constructor


// do what you need to do

} // release it. If an exception is thrown, the lock is also released.



You''ll want to lock as late as you can, and release as early as you can (usually when you''re done modifying something).

Share this post


Link to post
Share on other sites
> Each thread has its OWN stack of execution.

I think he meant ''glocal'' variables; local variables threads recognize as their own, but accessible globally (say, by the main object that owns the thread).

Try ''Thread-Local Storage'' or TLS variables. In Win32, you can use ''Tls[Set|Get]Value()'' functions. Under Unix rules, that depends; SGI has an area called ''PRDA->usr_prda.fill[]'', and Linux has something else named ''pthread_key_create()'' and ''pthread_setspecific()'', and Solaris has ''td_thr_get_info()'' et al.

-cb

Share this post


Link to post
Share on other sites
The idea about buying a book is generally a good one. However, considering I''ve already bought 2 $50+ books this month and it''s only the 13th ... You get the picture, I have to have my limits.

The web has essentially nil on threading so I am just learning as I go.

Now, don''t take this the wrong way but is asking a lot of questions (6) a bad thing? Have you read them all? They all deal with unique issues. Sorry if you think I am posting too much, but I thought that''s what this place was for. I''m not trolling, not spamming, not being unruly, just asking questions because I know people here are generally very knowledgable, and in general like to help. Otherwise, why are so many people here?

I could be obnoxious and ask the exact same questions many times or be one of those guys who "bumps" his posts to the top of the page every 2 minutes because no one has replied yet.

If/when run into troubles I first google for an answer, I then try a few searches here. If nothing specific to my problem turns up then I ask here. Thankfully, I usually get responses quickly. Sometimes I post again a short time later with an answer to my own question. I don''t sit on my hands and wait for the answer to be handed to me. I try new things and new searches, sometimes I get lucky and find it myself.

Sorry for my rant and I understand you were trying to help, just a little offended by the comment about my continuous posting. I think what I do is completely reasonable. Besides, I''m getting to know fingh and cbenoi1 through all these posts. At least it seems like they are the most helpful on this board in the fields I am working with Thanks guys.

I could post less often...but then you''d have to deal with multiple questions per post

Webby

Share this post


Link to post
Share on other sites
In response to cb

So given any function. If I spawn 4 threads with that function then they would all have their own copies of any variables declared inside of that function? So the only information I would have to protect would be the specific data that all threads operate on that would also be accessible by other functions, ie, variables not specifically declared inside of the function for the thread?

int sum; //global variable

void thrdFunc()
{
int local1;
int locat2;

local1 = //something;

local2 = //something else;


EnterCriticalSection(&crit);
sum = sum + local1 + local2;
LeaveCriticalSection(&crit);
}

So if each has it''s own execution stack then I don''t have to worry about placing critical sections around the uses of local1 and local2 even if I have a bajillion threads using this same function? I only have to protect the actual shared data.

That makes sense if it''s correct.

Thanks,
Webby

Share this post


Link to post
Share on other sites