Jump to content

Something I don't understand about concurrency

- - - - -

  • Please log in to reply
2 replies to this topic

#1
DarkLordofthePenguins

DarkLordofthePenguins

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 409 posts
I've been doing some research on concurrency using Wikipedia (I've realized it's an area I'm still deficient in). I'm learning about how locks and semaphores are used to ensure that two processes don't modify the same data at the same time.

Here's one thing I don't understand. Let's say two threads are going through an iterative loop. Thread A has the code:


for( int i = 0; i < 10; i++ ){

	str1[i] = fgetc( stdin );

}


while Thread B has the code:


for( int j = 0; j < 10; j++ ){

	str2[j] = fgetc( stdin );

}


Let's say that i and j occupy the same memory location (I know this is highly unlikely, but this is just an example).

Since each thread contains an I/O instruction, the threads will stop execution as they wait for input, resulting in a context switch. Both A and B will thus increment the memory location until the value is 10. The number of iterations for A and B add up to 10, but neither one of them goes through all the iterations. For instance, the value of j could be 4. A context switch occurs between B and A, and A increments it to 5, and when the context switch occurs again, B has the value 5 instead of 4. Thus 4 is skipped.

So basically my question is, if two threads modify the same memory location, and both of them depend on it being a certain value that may have been altered by the other thread (a possible cause of a deadlock), what is used to prevent this?
Programming is a journey, not a destination.

#2
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts

DarkLordofthePenguins said:

So basically my question is, if two threads modify the same memory location, and both of them depend on it being a certain value that may have been altered by the other thread (a possible cause of a deadlock), what is used to prevent this?

Nothing. If you do this your program is buggy. You could utilize a mutex here for the value of i/j, but if you do that, then any context switches to the other thread will simply be locked out until the previous thread is done using the value of i. You brought up mutexes and semaphores, but I'm answering this question in the context of language mechanics rather than utilization of a particular tool, since I think that's what you wanted...

Remember that C doesn't really give software writers very much in protection from doing bad things, so the language will go right ahead and let you do them. This could result in, at least in your example, undefined behavior. Imagine that the first thread increments i from 8 to 9, and checks if 9 is below 10 (it is), then context switches, where thread B increments j (bringing it from 9 to 10) and makes another context switch. Thread A will now attempt to write to str1[10] instead of str1[9], and if str1 only has 10 fields (from 0 to 9), this writing behavior is undefined.

The method C uses to prevent these things is programmer knowledge and active attempts to prevent it and make code thread safe. If that's not done, multithreading bugs are bound to creep in, as evidenced by the thousands of code bases out there with multithreading bugs in them.

Wow I changed my sig!

#3
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others
What you've explained is why mutex's and semaphores are so important. Using a shared resource between threads is dangerous, and can cause VERY unpredictable behavior. As a side note, this is also why trying to test applications that use a database applications, or any other external resource, can be so hard.

Imagine having two clients for a database. One is creating a new set of records, while the other is busy deleting "garbage" records. If there are not appropriate locks on the new records, the second client could delete the records the first client is planning to use.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users