I read some tutorial about threads and processes, it is said that the processes be scheduled by operating system kernel, and the threads can be managed and scheduled in a user mode.
I do not understand the saying "threads can be managed and scheduled in a user mode",
for example: the producer and consumer problem? is this a example for "scheduled in a user mode"? or can anyone explain me?
Not sure what tutorial you're looking at, but there are two ways that threads can be scheduled.
The first is user-mode scheduling, which basically mean that one process, using Green threads or perhaps fibers, schedules different threads to run without involving the operating system in its decision. This can be more portable across operating systems, but usually doesn't allow you to take advantage of multiple processors.
The second is kernel scheduling, which means that the various threads are visible to the kernel and are scheduled by it, possibly simultaneously on different processors. This can make thread creation and scheduling more expensive, however.
So it doesn't really depend on the problem that you are trying to solve. User-mode just means that the scheduling of threads happens without involving the operating system. Some early Java versions used Green/user-mode threads, but I believe most now use native/kernel threads.
EDIT:
Coding Horror has a nice overview of the difference between user and kernel mode.
Get a better tutorial? The official Java tutorials are quite good, and contain a lesson on concurrency, that also defines what process and thread mean.
PS: Whether threads are managed/scheduled in user mode is an implementation detail of the Java Virtual Machine that generally need not concern the application programmer.
Scheduled in user mode means you have control over the threads of your software but they are managed by the operating system kernel. So yes, the producer consumer problem is an example you normally handle yourself (but it is not directly related to user mode scheduling) by having two threads, a producer thread and a consumer thread. Both threads access the same shared recource. This resource has to be thread-safe, this means you have to make sure the shared resource does not get corrupted becouse both threads access it at the same time. Thread safety can either be guaranteed by using thread-safe data types or by manually locking or synchronizing your resource.
However, even if you have some control over your threads e.g. starting threads, stopping threads, make threads sleep etc. you do not have full control. The operating system is still managing which threads are allowed cpu time etc.
Related
I have read that each core can have two threads. So, if my application in prod uses three octa core servers, does that mean my application can only handle 48 concurrent requests? Or am I mixing two different things here?
Would appreciate any clarity here.
In Java, you can have as many threads as you like and you're not limited by how many CPU cores you have. I.e. Even if you only had one processor with a single core, you could still write a multi-threaded application.
The JVM will perform context switching - it will execute Thread 1 for some time, then Thread 2 for some time, then maybe Thread 1 again, and so on, switching between the threads. These switches between threads can occur after just a few milliseconds, so it can give the illusion that the threads are running in parallel.
On some applications, it is faster to just use a single thread - because this process of context switching just adds further expense.
I did actually write a small multi-threaded application the other day though. It had about 30 threads, and this was a use case where multithreading did make the app more efficient.
I had about 30 URLs that I needed to hit and retrieve some data from. If I did this in a single thread, there would be waiting time each time I made a request and waited for a response (thus, blocking the application). When multi-threading, other threads will have been able to run whilst this waiting went on.
I hope this makes sense. It'll be worth reading up on Java Context Switching for more info.
This is a good source on the topic: https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
I like the fact that threads can share some resources but they need to release their private resources in the end. Meantime, some computations may be obsolete and you kill them, using Task Manager. I am looking for the same thing done in one JVM process.
You say that thread.stop is unreliable and propose that my thread polls the interrupted flag instead. But, polling is not efficient, right? You do not want neither performance penalty nor polluting your code with ubiquitous if (interrupted) blocks. What is going to be the best appropriate option here?
Killing one process in an application that is composed of several interacting processes can be dangerous, but it is not usually as dangerous as killing a thread.
The ways in which one process depends on the state of another often are more limited. If the processes only interact through network communication, it probably won't be hard to design an application that can gracefully recover from having one of its processes killed. Likewise, if the processes interact through a shared transactional database.
It gets harder to handle a KILL safely if the processes interact through shared files. And it gets pretty close to impossible to guarantee the safety of an arbitrary KILL if the processes interact via shared memory.
Threads always interact via shared memory. A KILL that can't be handled, could come at any time. There's just no way to guarantee that killing some thread won't leave the whole program in a corrupt state.
That's why t.stop() is deprecated in Java. The real question should be, "why did they ever implement t.stop() in the first place?"
I've read somewhere that in Java scheduler, thread switching happens after execution of certain amount of instructions and not after a certain time (like schedulers used in operating systems). But the references were missing. I wanted to know if this is correct.
Java used to have a feature called GreenThreads, It was removed in 1.3. For all practical purposes we can assume that thread scheduling is directly influenced by the underlying operating systems's process/thread scheduling strategy. In this context, developers need to assume that threads are executed/scheduled randomly and should code/treat them as such.
On Linux the scheduling of Java threads is done using the Completely Fair Scheduler (CFS). For each CPU there is a run-queue and by default there is 24 ms in which all threads on a single-run queue should have a chance to run. So if there are 2 threads, each thread gets 12 ms, if there are 3 tasks, each thread gets 8 ms.
When tasks have a different priority, things chance. And also there is a minimum granularity to prevent reduce context switching overhead of many threads are running.
Recently I have read in a book that Concurrency is a fundamental tool for multiprocessor programming.
Than how is it useful for single core processor?
Concurrency is a fundamental tool for multiprocessor programming.
Yes, but it can also help in other areas. For instance, concurrency can also improve throughput on a single core system if the cpu is not the bottleneck (for instance, because the threads spend most of their time waiting for I/O from disk or the network).
Concurrency is helpful whenever there are multiple tasks that need to be run simultaneously. A very common example is in GUI programming; you don't want your UI to freeze up while the program waits for data to load from the disk or network, so you have a thread that just manages the UI elements (called the Event Dispatch Thread in Swing/AWT), and background threads that take care of communications or long-running calculations. The OS swaps them back and forth to make sure that the UI gets redrawn while other tasks are still active.
Being able to switch between running thread is useful for the perception of performance on a single core processor. In many systems, the graphical parts of the UI is updated by another thread than the one doing the work. It would be frustrating for the user to not have any feedback while a long task is running. Another useful application of concurrency on a single core, would be to start a long running task with low priority while the user is free to do other stuff at the same time.
We've been talking about threads in my operating system class a lot lately and one question has come to my mind.
Since Go, (and Java) uses User-space thread instead of kernel threads, doesn't that mean that you can't effectively take advantages of multiple cores since the OS only allocates CPU time to the process and not the threads themselves?
This seems to confirm the fact that you can't
Wikipedia also seems to think so
What makes you think Go uses User-space threads?
It doesn't. It uses OS-threads and can take advantage of multiple cores.
You might be puzzled by the fact that by default Go only uses 1 thread to run your program. If you start two goroutines they run in one thread. But if one goroutine blocks for I/O Go creates a second thread and continues to run the other goroutine on the new thread.
If you really want to unlock the full multi-core power just use the GOMAXPROCS() function.
runtime.GOMAXPROCS(4); //somewhere in main
Now your program would use 4 OS-threads (instead of 1) and would be able to fully use a e.g. 4 core system.
Most recent versions of Java to use OS threads, although there is not necessarily a one-to-one mapping with Java threads. Java clearly does work quite nicely across many hardware threads.
I presume that by "user-space threads" you mean (for example) Go's goroutines.
It is true that using goroutines for concurrency is less efficient than designing (by hand and by scientific calculations) a special-purpose algorithm for assigning work units to OS threads.
However: Every Go program is situated in an environment and is designed to solve a particular problem. A new goroutine can be started for each request that the environment is making to the Go program. If the environment is making concurrent requests to the Go program, a Go program using goroutines might be able to run faster than a serial program even if the Go program is using just 1 OS thread. The reason why goroutines might be able to process requests with greater speed (even when using just 1 OS thread) is that the Go program will automatically switch from goroutine A to goroutine B when the part of environment which is associated with A is momentarily unable to respond.
But yes, it is true that using goroutines and automatically assigning them to multiple OS threads is less efficient than designing (by hand and by scientific calculations) a special-purpose algorithm for assigning work units to OS threads.