多线程可以在单处理器系统上实现吗?

我一直遵循的概念是,多线程只能在多处理器系统上实现,在这种系统中,每个线程可以分配多个处理器,每个线程可以同时执行。在这种情况下没有任何调度,因为每个线程都有专用于它的独立资源。 但是我最近在某个地方读到过,我也可以在单处理器系统上进行多线程处理。 是否正确? 如果是,那么单处理器系统和多处理器系统的区别是什么?

86722 次浏览

Of course it can be done on a single-processor system, and in fact it's much easier that way. It works the same way as running multiple processes -- the kernel, via a timer interrupt or other similar mechanism, suspends one, saving its machine state, and replacing that by the previously-saved state of another -- the only difference being that two threads of the same process share the same virtual memory space, making the task-switch much more efficient.

Multi-threading on multi-processor systems is actually much more difficult, since you have issues of simultaneous access to memory from multiple cpus/cores, and all the nasty memory synchronization issues that arise out of that.

You can have more than four active threads on a quad core system. There is scheduling, unless you can guarantee that processes won't try to create more threads than there are processors.

Yes, you can have multiple threads on a single-core computer.

The difference between single processor and multi-processor systems is that a multi-processor system can indeed do more than one thing at a time. It can do N things at a time, where N is the number of processor cores. A single-processor core can only do one thing at a time. As WhozCraig said in his comment, it's the difference between actual and perceived concurrency.

I recenetly read it somewhere that I can do multithreading on single processor system as well. Is it correct? and if yes then what is the difference between single processor and multiple processor systems?

Yes you can do multithreading on a single processor system.

In multi-processor system , multiple threads execute , simultaneously on different cores. Eg- If there are two threads and two cores , then each thread would run on individual core.

In a single-processor system, multiple threads execute , one after the other or wait until one thread finishes or is preempted by the OS , depending on the thread priority and the OS policy.But the running threads , gives an illusion that they run simultaneous , relative to the required application response time of the User space application.

Time Comparison(Example):

if two threads take 10us each to execute, then on a 2 processor system , the net time take is 10us

if two threads take 10us each to execute, then on a 1 processor system , the net time take is 20us

Here's a very simplified example. It's actually a prototype for a program I'm building. It's a implementation of cooperative multitasking in a single thread.

main simply sets the quit flag to false, and populates an array of function pointers (the tasks), and then calls loop.

loop uses setjmp to set a return point for a non-local jump (a jump out of the function back to a previous location in the execution) and then proceeds to call the first task (function).

Each task ends with yield(). That is, none of the task functions actually return. Not only do they not contain a return; statement (which would be fine since they are void functions, ie. procedures), but they wouldn't reach the return even if it was there because yield jumps back to the setjmp call, this time yielding a 1 to the if statement in loop. The statement controlled by the if statement selects a different task before re-entering the return0 loop.

So each task function runs multiple times, yielding to the dispatcher (the if(setjmp... statement) which selects a new task to run.

#include <stdio.h>
#include <setjmp.h>


jmp_buf dispatch;
int ntasks;
void (*task[10])(void);
int quit;


void yield(void) {
longjmp(dispatch, 1);
}


void loop() {
static int i = 0;
if(setjmp(dispatch))
i = (i+1) % ntasks;
while(!quit)
task[i]();
}


int acc = 0;


void a(void) {
if (acc > 10) quit = 1;
printf("A\n");
yield();
}
void b(void) {
acc *= 2;
printf("B\n");
yield();
}
void c(void) {
acc += 1;
printf("C\n");
yield();
}


int main() {
quit = 0;
ntasks = 3;
task[0] = a;
task[1] = b;
task[2] = c;
loop();
return 0;
}

The difference between this example and a single-processor multitasking computer system is the real processor supports interrupting a task in the middle of execution and resuming it later from the same spot. This isn't really possible in a C simulation with tasks as single functions. However, the tasks could be composed of a sequence of C functions which each yield to the dispatcher (an array of function pointers, maybe, or a linked-list).

Yes, you totally can. Ages ago (Win 95?) we went from Cooperative Multitasking to Multithreading, because someone always screwed up the cooperative part. Every programm on your computer has at least one thread. Possibly more. And the CPU keep just switching between those all those threads like mad a few million times per second. If none of them has anything to do, it might even go idle for some time.

Multicore systems only mean that two or more of those threads might run in paralell.

However, it brings you a lot less to do so. All you can do with Multithreading on a Single Core machine is simulate Multitasking.

Mulitasking is enough to prevent the GUI thread from locking up because of a longrunning operation. However it is generally complicated to implement, unless you have some help from the Compiler or Langauge (like C# async...await). As a result, many GUI programmer just used Multithreading and Invoking to fake multitasking. If that code runs on single or multiple core does not mater for this.

Most importantly, Multitasking is NOT suited for CPU bound operations. But 95% of all Async problems are not CPU bound. They are Network or Disk Bound. On a singlecore computer, Multithreading also does not help with CPU bound stuff. If you got two threads that both need 100% CPU time (same programm or different one) but only one core to run them on, the CPU will just have to switch between running both at 49% and use the remaining 2% for all those other threads that only do a little bit.

Finally only very few problems can actually be Multithreaded. Just try to multithread the Fibonacci Sequence (one thread for each pair) without making it slower, more memory demanding and more complex.

tl;dr; You need Multithreading and a Multicore computer for CPU bound problems. Most async problems are not CPU bound. Multitasking is way enough. And you can totally multitask using threads, even on a single core machine.

In a multithreaded process on a single processor, the processor can switch execution resources between threads, resulting in concurrent execution. Concurrency indicates that more than one thread is making progress, but the threads are not actually running simultaneously. The switching between threads happens quickly enough that the threads might appear to run simultaneously.

In the same multithreaded process in a shared-memory multiprocessor environment, each thread in the process can run concurrently on a separate processor, resulting in parallel execution, which is true simultaneous execution. When the number of threads in a process is less than or equal to the number of processors available, the operating system's thread support system ensures that each thread runs on a different processor. For example, in a matrix multiplication that is programmed with four threads, and runs on a system that has two dual-core processors, each software thread can run simultaneously on the four processor cores to compute a row of the result at the same time.