1

This is the first time I am working with threads so I am sorry if this is a bad question. Shouldn't the output be consisted of "randomized" mains and foos? What I get seems to be a column of foos and a column of mains.

#include <iostream>
#include <thread>

void foo() {

    for (int i = 0; i < 20; ++i) {
        std::cout << "foo" << std::endl;
    }
}


int main(int argc, char** argv) {

    std::thread first(foo);
    for (int i = 0; i < 20; ++i) {
        std::cout << "main" << std::endl;
    }
    first.join();
    return 0;
}
Veritas
  • 2,150
  • 3
  • 16
  • 40

2 Answers2

2

There is a overhead starting a tread. So in this simple example the output is completely unpredictable. Both for loops running very short, and therefore if the thread start is only even a millisecond late, both code segments are executed sequentially instead of parallel. But if the operating system schedules the thread first, the "foo" sequence is showing before the "main" sequence.

Insert some sleep calls into the thread and the main function to see if they really run parallel.

#include <iostream>
#include <thread>
#include <unistd.h>

void foo() {

    for (int i = 0; i < 20; ++i) {
        std::cout << "foo" << std::endl;
        sleep(1);
    }
}


int main(int argc, char** argv) {

    std::thread first(foo);
    for (int i = 0; i < 20; ++i) {
        std::cout << "main" << std::endl;
        sleep(1);
    }
    first.join();
    return 0;
}

Using threads does not automatically enforce parallel execution of code segments, because if you e.g. have only one CPU in your system, the execution is switched between all processes and threads, and code segments are never running parallel.

There is a good wikipedia article about threads here. Especially read the section about "Multithreading".

Flovdis
  • 2,945
  • 26
  • 49
  • This seems to do the job. Just a question, using my code I would either get a column of foos and then a column of mains or a column of mains and then a column of foos. I understand how the starting overhead of a thread could result in the latter but how does it explain the former case? – Veritas Apr 07 '14 at 07:50
  • @Potatoswatter Yes, overhead is probably the better word. Thank you! – Flovdis Apr 07 '14 at 07:52
  • @Veritas It's as I told, the behaviour is unpredictable. The scheduler of the operating system will give one thread a slice of time, but which thread get this slice depends largely on the operating system and the current situation. – Flovdis Apr 07 '14 at 07:56
  • So it seems to have more to do with the scheduler than the thread overhead. Anyway this was a good answer, thanks for your help! – Veritas Apr 07 '14 at 08:00
  • @Veritas It has to do with both. Starting a thread needs time. E.g. thread A is starting a new thread B. The time to start thread B is accounted to thread A. So after thread B is ready to run, the start could have "eaten up" the remaining scheduled time of thread A. In this case most likely the code of thread B is starting first. But if there is scheduled time left for thread A, most likely the rest of the code in thread A is executed. – Flovdis Apr 07 '14 at 08:09
  • 1
    sleep(1) is not a good idea unless the other thread is not in queue and it would take atleast time current thread would sleep. I would prefer a [yield](http://www.cplusplus.com/reference/thread/this_thread/yield/) – Mohit Jain Apr 07 '14 at 12:17
  • @MohitJain You are absolutely right in case of productive software, but I understand this as an educational example. The asker would like to see a demonstration how threads execute in parallel. The `sleep` function has the benefit, slowing down the execution to be able to watch the example program "at work". – Flovdis Apr 08 '14 at 10:43
1

After cout try to yield. This may honor any waiting thread. (Although implementation dependent)

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
  • 1
    Prefer yield over sleep. http://stackoverflow.com/questions/5304324/whats-the-difference-between-yield-and-sleep – Mohit Jain Apr 07 '14 at 08:21