Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C++ and pthread simple program help

  1. Feb 25, 2015 #1

    perplexabot

    User Avatar
    Gold Member

    Hey all. I am currently trying to brush up on my multithreading "skills" (I dare say) that I learned in my undergrad class. I have the following code that I am trying to run:

    Code (Text):
    #include <pthread.h>
    #include <iostream>
    using namespace std;
    void* func1(void*);

    int main(int argc, char** argv){
            pthread_t t1;
            //func1(NULL);
            int rc = pthread_create(&t1,NULL,func1,NULL);
            func1(NULL);
            return 0;
    }

    void* func1(void* trash){
        for(int i = 0; i < 10; i++){
            cout<<i<<endl;
        }
    }
    I am compiling using g++ with the following:
    Code (Text):
    g++ -pthread main.cpp
    No errors are encountered BUT when I execute
    Code (Text):
    ./a.out
    in the terminal I don't get anything. I was hoping to get the sequence of numbers from 0 to 9...

    Any help on this would be greatly appreciated as I have a job interview tomorrow and I believe I will be questioned about threads : /

    Thank you for reading.


    EDIT------------------------------------------------------
    Hey again. So I have been playing around with this little program and I ran into something interesting (maybe not so interesting if you know what is going on... I don't tho!). If i place the following extra line in the code (a snippet):
    Code (Text):
    int main(int argc, char** argv){
            pthread_t t1;
            //func1(NULL);
            int rc = pthread_create(&t1,NULL,func1,NULL);
            func1(NULL); //<---- extra line
            return 0;
    }
    I am able to see the output of func1 twice on the terminal!!! Which means the thread is working and so is the function call to func1 in main.

    So why is it that when I remove this extra line I am not able to see the new thread's function output???!?!??
     
    Last edited by a moderator: Feb 27, 2015
  2. jcsd
  3. Feb 26, 2015 #2

    Filip Larsen

    User Avatar
    Gold Member

    You start a thread but then exit your main method before the thread had a chance to complete. In this particular case you may want to consider using pthread_join [1], but in general there are many ways to synchronize the behavior of multiple threads, each with its own set of critical subtleties.

    [1] http://linux.die.net/man/3/pthread_join
     
  4. Feb 26, 2015 #3

    perplexabot

    User Avatar
    Gold Member

    Thank you! I actually just finished experimenting with join(). So you are saying that if main() just so happened to be running for a bit longer (like say with a sleep() or a join()),my created thread would have executed? So join() guarantees this to happen.?.
     
  5. Feb 26, 2015 #4

    Filip Larsen

    User Avatar
    Gold Member

    Yes, the call to join() will, in normal situations, only return once the thread has terminated.

    If you try use a sleep or a similar unsynchronized approach to make the thread complete before main() there would be no such guarantee. In some situations main() may terminate before the thread and in other situations it may be the opposite. The code would then have a race-condition [1] which is almost always a bad thing.

    [1] http://en.wikipedia.org/wiki/Race_condition
     
  6. Feb 26, 2015 #5

    rcgldr

    User Avatar
    Homework Helper

    Here's an example std c++ code that spawns two threads, with the ability for the main thread to pause, continue, or terminate the process. Both threads read from a "current" array at the same time, with the "producer" thread updating the "other" array, and the "consumer" thread displaying the "current" array. Each thread uses an event for synchronization, and each thread swaps it's own pair of pointers to alternate between the two arrays, a type of double buffering. Note that .join() is only used when waiting for the threads to terminate.

    Code (Text):

    #include <atomic>
    #include <chrono>
    #include <condition_variable>
    #include <iostream>
    #include <mutex>
    #include <thread>

    struct test
    {
        double x[10], y[10];
        double *cxpx = &x[0];               // ptrs for change_x
        double *cxpy = &y[0];
        double *pxpx = &x[0];               // ptrs for print_x
        double *pxpy = &y[0];
        std::atomic<bool> stop = false;
        std::atomic<bool> pause = false;
    };

    class handle_Event
    {
    private:
        bool signalled;
        std::condition_variable_any c_v;
        std::mutex mtx;

    public:
        handle_Event()
        {
            signalled = false;
        }
        ~handle_Event()
        {
        }
        void signal(void)
        {
            std::lock_guard<std::mutex> lck(mtx);
            signalled = true;
            c_v.notify_one();
        }
        void reset(void)
        {
            std::lock_guard<std::mutex> lck(mtx);
            signalled = false;
        }
        bool wait(void)
        {
            std::lock_guard<std::mutex> lck(mtx);
            while (!signalled)
                c_v.wait(mtx);
            return signalled;
        }
    };

    handle_Event hndl_change_x, hndl_print_x, hndl_continue;

    void change_x(test &t)
    {
        while (1){
            hndl_change_x.wait();           // wait
            hndl_change_x.reset();
            if (t.stop.load())              // exit if stop flag set
                break;
            const double f = t.cxpx[0];
            for (uint16_t i = 0; i < 10; i++)
                t.cxpy[i] = ((i + 1) % 10) ? t.cxpx[i + 1] : f;
            std::swap(t.cxpx, t.cxpy);
            hndl_print_x.signal();          // ready for print
        }
    }

    void print_x(test &t)
    {
        while (1){
            hndl_print_x.wait();            // wait
            hndl_print_x.reset();
            if (t.pause.load()){            // pause if pause set
                hndl_continue.wait();
                hndl_continue.reset();
            }
            if (t.stop.load())              // exit if stop flag set
                break;
            hndl_change_x.signal();         // ready for change
            for (uint16_t j = 0; j < 10; j++)
                std::cout << t.pxpx[j] << " ";
            std::cout << std::endl;
            std::swap(t.pxpx, t.pxpy);
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
        }
    }

    int main(void)
    {
        double x0[] = { 0., 1., 2., 3., 4., 5., 6., 7., 8., 9. };
        test var;
        for (uint16_t i = 0; i < 10; i++) var.x[i] = x0[i];
        char hit = 0;

        std::thread thread_change_x(change_x, std::ref(var));
        std::thread thread_print_x(print_x,   std::ref(var));
        hndl_print_x.signal();          // start with print

        while (1){                      // wait for input
            if ((hit = std::cin.get()) == 'x')
                break;
            if ((hit == 'p') && (var.pause.load() == false))
                var.pause.store(true);
            if ((hit == 'c') && (var.pause.load() == true)){
                var.pause.store(false);
                hndl_continue.signal();
            }
        }
        var.stop.store(true);           // stop threads
        hndl_change_x.signal();
        hndl_print_x.signal();
        hndl_continue.signal();
        thread_change_x.join();         // wait for child threads to stop
        thread_print_x.join();
        return 0;
    }
     
     
  7. Feb 28, 2015 #6

    perplexabot

    User Avatar
    Gold Member

    Thank you guys for your replies and help. I actually read them right before my interview which provided me with some confidence. Nothing about threads was asked (mostly C++ sockets), I got a call from them after for a second interview. Maybe my thread studying will come in handy for that. Thanks again.
     
  8. Mar 9, 2015 #7
    If you just want to open a thread prefer a modern lib like BoostThread. Simple to use, simple to understand. Boost is very popular.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: C++ and pthread simple program help
  1. Help in C programming (Replies: 1)

Loading...