Metafity Metafity - 3 months ago 16
C++ Question

Threads exiting prematurely

I have the following piece of code, meant to create two threads and execute them indefinitely. But when run, it exits after some iterations.

#include <iostream>
#include "error.h"
#include <cstdlib>
#include <pthread.h>
#include <string>
#include <time.h>
#include <sys/wait.h>
using namespace std;
#define NUM_THREADS 2
#define TIME_OUT 3

void *GoBackN(void* arg) {
while(true) cout<<"Thread executing"<<endl;
}
int main()
{
pthread_t t[NUM_THREADS];
pthread_create((&t[0]),NULL,&GoBackN,NULL);
pthread_create((&t[1]),NULL,&GoBackN,NULL);
wait(NULL);
return 0;
}


Output -

Thread executing

Thread executing

Thread executing

Thread executing

Thread executing

Thread executing

Thread executing

Thread executing

Thread executing

Thread executing

Thread executing

Process returned 0;

I'm compiling on g++, and running a linux machine.

Answer

You have three threads and you allow the main thread to exit.

#include <iostream>
#include "error.h"
#include <cstdlib>
#include <pthread.h>
#include <string>
#include <time.h>
#include <sys/wait.h>
using namespace std;
#define NUM_THREADS 2
#define TIME_OUT 3

void* GoBackN(void* arg) {
   while(true)  cout<<"Thread executing"<<endl;
}

int main() // main thread starts here
{
    pthread_t t[NUM_THREADS];
    pthread_create((&t[0]),NULL,&GoBackN,NULL); // second thread starts here
    pthread_create((&t[1]),NULL,&GoBackN,NULL); // third thread starts here
    wait(NULL); // doesn't wait for very long (zero time)
    // ...
    // main thread keeps running here...
    // ...
    return 0; // whoops main thread ends closing program
}

You could put an infinite loop (or an infinite wait) in the main thread to stop it exiting the program.

int main()
{
    pthread_t t[NUM_THREADS];
    pthread_create((&t[0]),NULL,&GoBackN,NULL);
    pthread_create((&t[1]),NULL,&GoBackN,NULL);
    wait(NULL); // doesn't wait for very long (zero time)
    // ...
    // loop in the main thread too
    while(true)  cout<<"Main thread executing"<<endl;
    // ...
    return 0; // now we don't get here
}

Or more typically join the threads waiting for them to exit:

int main() // main thread starts here
{
    pthread_t t[NUM_THREADS];
    pthread_create((&t[0]),NULL,&GoBackN,NULL); // second thread starts here
    pthread_create((&t[1]),NULL,&GoBackN,NULL); // third thread starts here
    wait(NULL); // doesn't wait for very long (zero time)
    // ...
    // join threads here
    pthread_join(t[0], nullptr);
    pthread_join(t[1], nullptr);
    // ...
    return 0; // we get here when other threads end
}

Now the main thread is suspended and does not consume any CPU time while the other threads are running.

If you are using a modern compiler with C++11 support you can use the Standard Library threads something like this:

#include <thread>
#include <chrono>
#include <vector>
#include <sstream>
#include <iostream>

const int number_of_threads = 5;

// nasty little MACRO to provide synchronized output (crude but works)
#define SYNC_OUT(m) do{std::ostringstream o; o << m << '\n'; std::cout << o.str();}while(0)

void GoBackN(int id) {
   while(true)
   {
       SYNC_OUT("Thread: " << id << " executing");
       std::this_thread::sleep_for(std::chrono::milliseconds(500));
   }
}

int main() // main thread starts here
{
    std::vector<std::thread> threads;

    for(int i = 0; i < number_of_threads; ++i)
        threads.emplace_back(GoBackN, i); // start new thread

    // ...
    // join threads here
    for(auto&& thread: threads)
        thread.join();
}