Arun K
Arun K

Reputation: 63

How I can run two threads parallelly one by one?

In C++ how i can write two parallel threads which will work one by one.For example in below code it need to print 0 t 100 sequentially.In below code the numbers are printing ,but all are not sequential.I need to print like 1,2,3,4,5,6.....99.If any body know , try to add with sample code also.

    #pragma once
#include <mutex>
#include <iostream>
#include <vector>
#include <thread>
#include <condition_variable>
using namespace std;
class CuncurrentThread
{
public:
    mutex mtx;
    condition_variable cv;
    static bool ready;
    static bool processed;
    void procThread1()
    {
        for (int i = 0; i < 100; i += 2)
        {
            unique_lock<mutex> lk(mtx);
            cv.notify_one();
            if(lk.owns_lock())
                cv.wait(lk);
            cout << "procThread1 : " << i << "\n";
            lk.unlock();
            cv.notify_one();
        }
    };
    void procThread2()
    {
        for (int i = 1; i < 100; i += 2)
        {
            unique_lock<mutex> lk(mtx);
            cv.notify_one();
            if (lk.owns_lock())
                cv.wait(lk);
            cout << "procThread2 : " << i << "\n";
            lk.unlock();
            cv.notify_one();
        }
    };
    static void ThreadDriver(CuncurrentThread* thr)
    {
        vector<thread> threads;
        threads.push_back(thread(&CuncurrentThread::procThread1, thr));
        threads.push_back(thread(&CuncurrentThread::procThread2, thr));

        for (auto& thread : threads) 
            thread.join();

    };
};
bool CuncurrentThread::ready = false;
int main()
{
    CuncurrentThread tr;
    CuncurrentThread::ThreadDriver(&tr);
    
}

Upvotes: 1

Views: 883

Answers (2)

Pepijn Kramer
Pepijn Kramer

Reputation: 12847

Assuming you have a valid use case for using two threads like this, here is an example. I prefer using std::async over std::thread it has better abstraction and information exchange with the main thread. The example is written for 2 threads but can easily be changed to more threads.

Live demo here : https://onlinegdb.com/eQex9o_nMz

#include <future>
#include <condition_variable>
#include <iostream>

// Setup a helper class that sets up
// the three things needed to correctly
// use a condition variable
// 1) a mutex
// 2) a variable
// 3) a condition_variable (which is more of a signal then a variable)
//
// also give this class some functions
// so the the code becomes more self-explaining

class thread_switcher_t
{
public:
    void thread1_wait_for_turn()
    {
        std::unique_lock<std::mutex> lock{ m_mtx };
        m_cv.wait(lock, [&] {return (thread_number==0); });
    }

    void thread2_wait_for_turn()
    {
        std::unique_lock<std::mutex> lock{ m_mtx };
        m_cv.wait(lock, [&] {return (thread_number==1); });
    }

    void next_thread()
    {
        std::unique_lock<std::mutex> lock{ m_mtx };
        thread_number = (thread_number + 1) % 2;
        m_cv.notify_all();
    }

private:
    std::size_t thread_number{ 0 };
    std::mutex m_mtx;
    std::condition_variable m_cv;
};


int main()
{
    thread_switcher_t switcher;
    
    auto future1 = std::async(std::launch::async, [&]
    {
        for(std::size_t n = 0; n <= 100; n+=2)
        {
            switcher.thread1_wait_for_turn();
            std::cout << "thread 1 : " << n << "\n";
            switcher.next_thread();
        }
    });

    auto future2 = std::async(std::launch::async, [&]
    {
        for (std::size_t n = 1; n <= 100; n += 2)
        {
            switcher.thread2_wait_for_turn();
            std::cout << "thread 2 : " << n << "\n";
            switcher.next_thread();
        }
    });

    future1.get();
    future2.get();

    return 0;
}

Upvotes: 1

kiner_shah
kiner_shah

Reputation: 4641

You can use ready variable as a condition for condition variable.

#include <mutex>
#include <iostream>
#include <vector>
#include <thread>
#include <condition_variable>
using namespace std;

class CuncurrentThread
{
public:
    mutex mtx;
    condition_variable cv;
    static bool ready;
    //static bool processed;
    void procThread1()
    {
        for (int i = 0; i < 100; i += 2)
        {
            unique_lock<mutex> lk(mtx);
            // cv.notify_one();
            // if(lk.owns_lock())

            // wait until this condition is true i.e. until ready is false
            cv.wait(lk, [&]() { return !ready; });
            cout << "procThread1 : " << i << "\n";

            // set ready to true and notify waiting thread
            ready = true;
            lk.unlock();
            cv.notify_one();
        }
    };
    void procThread2()
    {
        for (int i = 1; i < 100; i += 2)
        {
            unique_lock<mutex> lk(mtx);
            // cv.notify_one();
            // if (lk.owns_lock())

            // wait until this condition is true i.e. until ready is true
            cv.wait(lk, [&]() { return ready; });
            cout << "procThread2 : " << i << "\n";

            // set ready to false and notify waiting thread
            ready = false;
            lk.unlock();
            cv.notify_one();
        }
    };
    static void ThreadDriver(CuncurrentThread* thr)
    {
        vector<thread> threads;
        threads.push_back(thread(&CuncurrentThread::procThread1, thr));
        threads.push_back(thread(&CuncurrentThread::procThread2, thr));

        for (auto& thread : threads) 
            thread.join();

    };
};
bool CuncurrentThread::ready = false;
int main()
{
    CuncurrentThread tr;
    CuncurrentThread::ThreadDriver(&tr);
}

Link where I tested this: https://godbolt.org/z/4jEns16oq

Upvotes: 0

Related Questions