• Post Reply Bookmark Topic Watch Topic
  • New Topic

Understanding threads

 
Ryan McClain
Ranch Hand
Posts: 153
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am taking my first steps in understanding threads.

Is the following statement correct?
"Even with threads, (portions of) applications don't execute at the same time. With single core, the CPU would switch between applications by giving each application a time slice. With multi-core and threads, a switch is still happening, even if multiple threads are executing - this being the 'context switch'. The CPU has to do a context switch on the threads."

So I am trying to understand if threads really do happen at the same time.

I am not too sure of my statement.
Corrections if needed please.

 
Ulf Dittmer
Rancher
Posts: 42970
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think that's correct. On a multi-core or multi-CPU machine, no context switch needs to happen. That's not a guarantee that concurrent threads will in fact execute in parallel, but a sufficiently smart JVM would in principal be capable of doing that.
 
Ryan McClain
Ranch Hand
Posts: 153
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am confused. How would two threads (one on each core) be able to execute exactly at the same time (the same nano second, on the same part of memory, on the same pointer, etc.)? Then which end result would be the correct one if one thread would add +1 to a sum and the other one would do that as well? This would be one of the concurrency problems. Wouldn't that require a system of managing the threads by letting one do its thing for a few nanoseconds, while the other waits and then let the other have its turn?

Or perhaps 'at the same time' could be something like a webserver:
- a thread listening for connections
- a thread handling HTTP requests

The listener thread listens, passes request to handler thread and then goes back to listening. I'm not sure if this is truly parallel execution. Wouldn't visitor2 have to wait for the listener thread to handle visitor1? Or perhaps there could be multiple listening threads? A bit confusing. The way I understand parallel execution is how I described it above.

I'm currently reading this in trying to understand it:
http://tutorials.jenkov.com/java-concurrency/index.html


 
Henry Wong
author
Sheriff
Posts: 22515
109
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ulf Dittmer wrote:I don't think that's correct. On a multi-core or multi-CPU machine, no context switch needs to happen. That's not a guarantee that concurrent threads will in fact execute in parallel, but a sufficiently smart JVM would in principal be capable of doing that.


I will go one step further... Modern processors can run stuff in parallel, even with a single thread running a single core. Certain adjacent instructions (depending on the pairing) can be executed in parallel, allowing for more than one instruction to be executed per cycle.

Henry
 
Ulf Dittmer
Rancher
Posts: 42970
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ryan McClain wrote:How would two threads (one on each core) be able to execute exactly at the same time (the same nano second, on the same part of memory, on the same pointer, etc.)?

So far we've been talking about threads in general - there was no mention of concurrent threads operating on shared data. Shared mutable data needs to be protected from concurrent access, for example by synchronization. If you've programmed web apps, this should be a familiar concept.
 
Henry Wong
author
Sheriff
Posts: 22515
109
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ryan McClain wrote:I am confused. How would two threads (one on each core) be able to execute exactly at the same time (the same nano second, on the same part of memory, on the same pointer, etc.)?


Different cores uses different circuitry, and hence, can do stuff in parallel.

As for the "same memory" part of the question, in that case, they can't. The cores have to share the cache, and main memory, so if the cores are trying to use the same memory -- they will take turns.

Ryan McClain wrote:Then which end result would be the correct one if one thread would add +1 to a sum and the other one would do that as well? This would be one of the concurrency problems. Wouldn't that require a system of managing the threads by letting one do its thing for a few nanoseconds, while the other waits and then let the other have its turn?


That's the application's problem. It is the application job to make sure that threads don't have race condition -- or deal with the ramifications... but yeah, if the application has threads that has race conditions, running them on cores will have race conditions.

Henry
 
Henry Wong
author
Sheriff
Posts: 22515
109
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ryan McClain wrote:
Or perhaps 'at the same time' could be something like a webserver:
- a thread listening for connections
- a thread handling HTTP requests


The first example is in regards to I/O, and is not related to parallelism at the processor level.

In the second example, HTTP requests should be stateless. And there should be no sharing of data as two cores are processing the same page... but if there is, then it is the applications job to deal with it.

Henry
 
Ryan McClain
Ranch Hand
Posts: 153
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So as I understand it: threads can run in parallel but when they do so, they could cause concurrency problems in the case of write operations. These problems have to be solved by the programmer.

I realize now I am referring to concurrency problems that occur when writing to the same memory has to occur in parallel. Reading operations don't cause concurrency problems I think.

Finally, is it correct to assume that when concurrency problems (like race conditions) can occur, threads no longer happen at the same time but have to take turns because the programmer has to make sure there are no concurrency problems in his application?

Henry Wong wrote:As for the "same memory" part of the question, in that case, they can't. The cores have to share the cache, and main memory, so if the cores are trying to use the same memory -- they will take turns.


Now that I think of it: even if two threads write at the same time, they aren't really writing at the same time because this is what could happen:

thread1: read value out of CPU register
thread1: sleep
thread2: read value out of CPU register
thread2: write value to memory
thread2: sleep
thread1: awake
thread1: write value from CPU register because its condition said "add 1 if sum is 0" and didn't take into account thread2 already wrote to it, so in its own stack the sum is still 0 because prior to sleeping, that's what it read from memory. This is where concurrency problems occur which are again a responsibility for application design.

As far as I understand from this example, thread1 isn't really writing at the same time as thread2, or is it? If both write at the same time, the result is going to be either 1 or 2, but not 1 and 2 at the same time. Kind of like a Schrödinger's cat situation.

So, like you said: they take turns.

Still confusing.
 
Ulf Dittmer
Rancher
Posts: 42970
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If for some reason they're trying to access the same CPU register, then yes - they have to take turns. But that wouldn't happen with multi-core CPUs or multi-CPU machines, because the registers are duplicated just like the rest of the CPU.

is it correct to assume that when concurrency problems (like race conditions) can occur, threads no longer happen at the same time but have to take turns because the programmer has to make sure there are no concurrency problems in his application?

That's the theory, anyway :-) In practice thread-safe programming is not trivial, since you want to use the synchronization mechanism that least impacts concurrency. So you may need to plan your datastructures and methods somewhat to accommodate that.
 
Henry Wong
author
Sheriff
Posts: 22515
109
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ryan McClain wrote:
Now that I think of it: even if two threads write at the same time, they aren't really writing at the same time because this is what could happen:

thread1: read value out of CPU register
thread1: sleep
thread2: read value out of CPU register
thread2: write value to memory
thread2: sleep
thread1: awake
thread1: write value from CPU register because its condition said "add 1 if sum is 0" and didn't take into account thread2 already wrote to it, so in its own stack the sum is still 0 because prior to sleeping, that's what it read from memory. This is where concurrency problems occur which are again a responsibility for application design.


Different cores have different registers. It would actually be pretty useless if cores shared registers, as they used registers constantly -- even the simplest of calculations go through some registers.

Henry
 
Ryan McClain
Ranch Hand
Posts: 153
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ulf Dittmer wrote:In practice thread-safe programming is not trivial, since you want to use the synchronization mechanism that least impacts concurrency. So you may need to plan your datastructures and methods somewhat to accommodate that.

From what I've read on thread-safe programming, a thread has to do its work in the most narrow scope possible: get the lock, do action, release lock. All of this in method local scope. :-)
 
Ryan McClain
Ranch Hand
Posts: 153
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ulf Dittmer wrote:
Ryan McClain wrote:How would two threads (one on each core) be able to execute exactly at the same time (the same nano second, on the same part of memory, on the same pointer, etc.)?

So far we've been talking about threads in general - there was no mention of concurrent threads operating on shared data. Shared mutable data needs to be protected from concurrent access, for example by synchronization. If you've programmed web apps, this should be a familiar concept.

I am just getting started on programming web apps, so this is my first step in understanding a system of synchronizing concurrent access.
 
Ulf Dittmer
Rancher
Posts: 42970
73
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK. Shared mutable data is the key point in this. If data is shared between threads, but is not mutable (meaning, it is not changed), then no synchronization is necessary. Same if the data is mutable, but not shared (kind of obvious, a single thread can't be in contention with itself :-). The need for synchronization arises only if multiple threads access the same data, and it can change while they do so.

The "while they do so" part is also important - for example, if some data structure is only changed at application startup time (maybe some kind of cache is filled), but not later during the runtime of the application, then there is also no need for synchronization.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!