It seems that the distinction between fibers and threads is that fibers are cooperatively scheduled, whereas threads are preemptively scheduled.  The point of the scheduler seems like a way to make an otherwise serial processor resource act in a parallel way, by time-sharing the CPU.  However, on a dual-core processor with each core running its own thread, I assume there's no need to pause the execution of one thread for the other to continue because they're not time-sharing a single processor.So, if the difference between threads and fibers is the way they are interrupted by the scheduler, and interrupting is not necessary when running on physically separate cores, why can't fibers take advantage of multiple processor cores when threads can?Sources of confusion:..mainly wikipediahttp://en.wikipedia.org/wiki/Fiber_%28computer_science%29A disadvantage is that fibers cannot utilize multiprocessor machines without also using preemptive threadshttp://en.wikipedia.org/wiki/Computer_multitasking#Multithreading...[fibers] tend to lose some or all of the benefits of threads on machines with multiple processors.
Why can't fibers utilize multiple processors?
parallel computing;threads;multi tasking
The main distinction, as you point out in your question, is whether or not the scheduler will ever preempt a thread.  The way a programmer thinks about sharing data structures or about synchronizing between threads is very different in preemptive and cooperative systems.In a cooperative system (which goes by many names, cooperative multi-tasking, nonpreemptive multi-tasking, user-level threads, green threads, and fibers are five common ones currently) the programmer is guaranteed that their code will run atomically as long as they don't make any system calls or call yield().  This makes it particularly easy to deal with data structures shared between multiple fibers.  Unless you need to make a system call as part of a critical section, critical sections don't need to be marked (with mutex lock and unlock calls, for example).  So in code like:x = x + yy = 2 * xthe programmer needn't worry that some other fiber could be working with the x and y variables at the same time.  x and y will be updated together atomically from the perspective of all the other fibers.  Similarly, all the fibers could share some more complicated structure, like a tree and a call like tree.insert(key, value) would not need to be protected by any mutex or critical section.In contrast, in a preemptive multithreading system, as with truly parallel/multicore threads, every possible interleaving of instructions between threads is possible unless there are explicit critical sections.  An interrupt and preemption could become between any two instructions.  In the above example: thread 0                thread 1                         < thread 1 could read or modify x or y at this point read x                         < thread 1 could read or modify x or y at this point read y                         < thread 1 could read or modify x or y at this point add x and y                         < thread 1 could read or modify x or y at this point write the result back into x                         < thread 1 could read or modify x or y at this point read x                         < thread 1 could read or modify x or y at this point multiply by 2                         < thread 1 could read or modify x or y at this point write the result back into y                         < thread 1 could read or modify x or y at this pointSo to be correct on a preemptive system, or on a system with truly parallel threads, you need to surround every critical section with some kind of synchronization, like a mutex lock at the beginning and a mutex unlock at the end.Fibers are thus more similar to asynchronous i/o libraries than they are to preemptive threads or truly parallel threads.  The fiber scheduler is invoked and can switch fibers during long latency i/o operations.  This can give the benefit of multiple simultaneous i/o operations without requiring synchronization operations around critical sections.  Thus using fibers can, perhaps, have less programming complexity than preemptive or truly parallel threads, but the lack of synchronization around critical sections would lead to disastrous results if you tried to run the fibers truly simultaneously or preemptively.