printing odd and even number printing alternately using threads in C++

前端 未结 10 1091
后悔当初
后悔当初 2021-01-03 02:09

Odd even number printing using thread I came across this question and wanted to discuss solution in C++ . What I can think of using 2 binary semaphores odd and even semapho

相关标签:
10条回答
  • 2021-01-03 02:48
    #include <iostream>
    #include <thread>
    #include <mutex>
    
    std::mutex mu;
    unsigned int change = 0;
    
    void printConsecutiveNumbers(int start, int end,unsigned int consecutive)
    {
        int x = start;
        while (x < end)
        {
            //each thread has check there time is coming or not
            if (change % consecutive == start)
            {
                std::unique_lock<std::mutex> locker(mu);
                std::cout << "Thread " << start << " -> " << x << std::endl;
                x += consecutive;
                change++;
                //to counter overflow
                change %= consecutive;
            }
        }
    }
    
    int main()
    {
        //change num = 2 for printing odd and even
        const int num = 7;
        const int endValue = 1000;
        std::thread threads[num];
        //Create each consecutive threads
        for (int i = 0; i < num; i++)
        {
            threads[i] = std::thread(printConsecutiveNumbers, i, endValue, num);
        }
    
        //Joins all thread to the main thread
        for (int i = 0; i < num; i++)
        {
            threads[i].join();
        }
    
        return 0;
    }
    
    0 讨论(0)
  • 2021-01-03 02:49

    Please see below working code (VS2005)

    #include <windows.h>
    #include <stdlib.h>
    
    #include <iostream>
    #include <process.h>
    
    #define MAX 100
    int shared_value = 0;
    
    CRITICAL_SECTION cs;
    
    unsigned _stdcall even_thread_cs(void *p)
    {
    
        for( int i = 0 ; i < MAX ; i++ )
        {
            EnterCriticalSection(&cs);
    
            if( shared_value % 2 == 0 )
            {
                printf("\n%d", i);
            }
    
    
            LeaveCriticalSection(&cs);
    
        }
        return 0;
    }
    
    unsigned _stdcall odd_thread_cs(void *p)
    {
        for( int i = 0 ; i < MAX ; i++ )
        {
            EnterCriticalSection(&cs);
    
            if( shared_value % 2 != 0 )
            {
                printf("\n%d", i);
            }
    
            LeaveCriticalSection(&cs);  
    
        }
    
        return 0;
    }
    
    
    int main(int argc, char* argv[])
    {
         InitializeCriticalSection(&cs);
    
        _beginthreadex(NULL, NULL, even_thread_cs, 0,0, 0);
        _beginthreadex(NULL, NULL, odd_thread_cs, 0,0, 0);
    
        getchar();
        return 0;
    }
    

    Here, using shared variable shared_value, we are synchronizing the even_thread_cs and odd_thread_cs. Note that sleep is not used.

    0 讨论(0)
  • 2021-01-03 02:50

    This is simple solution using single function.

    #include <iostream>
    #include <thread>
    #include <condition_variable>
    using namespace std;
    
    mutex mu;
    condition_variable cond;
    int count = 1;
    
    void PrintOddAndEven(bool even, int n){
        while(count < n){
            unique_lock<mutex> lk(mu);
            cond.wait(lk, [&](){return count%2 == even;});
            cout << count++ << " ";
            lk.unlock();
            cond.notify_all();
        }
    }
    
    int main() {
        int n = 10;
        thread t1(PrintOddAndEven, true, n);
        thread t2(PrintOddAndEven, false, n);
    
        t1.join();
        t2.join();
        return 0;
    }
    
    0 讨论(0)
  • 2021-01-03 02:58

    I fail to understand why you want to use three separate threads for a serial behavior. But I will answer anyway:)

    One solution would be to use a modified producer/consumer pattern with a prioritized queue between producers and consumers. The sort operation on the queue would depend on the integer value of the posted message. The consumer would peek an element in the queue and check if it is the next expected element. If not, it would sleep/wait.

    A bit of code:

    class Elt implements Comparable<Elt> {
      int value;
      Elt(value) { this.value=value; }
      int compare(Elt elt);
    }
    
    class EltQueue extends PriorityBlockingQueue<Elt> { // you shouldn't inherit colelctions, has-a is better, but to make it short
      static EltQueue getInstance(); // singleton pattern
    }
    
    class Consumer{
      Elt prevElt = new Elt(-1);
      void work()
      {
        Elt elt = EltQueue.getInstance().peek();
        if (elt.getValue() == prevElt.getValue()+1)) {
          EltQueue.getInstance().poll();
          //do work on Elt
        }
      }
    }
    
    class Producer {
      int n=0; // or 1!
      void work() {
        EltQueue.getInstance().put(new Elt(n+=2));
      }
    }
    
    0 讨论(0)
  • 2021-01-03 03:02

    Using condition_variable

    #include <iostream>
    #include <thread>
    #include <mutex>
    #include <condition_variable>
    
    std::mutex mu;
    std::condition_variable cond;
    int count = 1;
    
    void PrintOdd()
    {
        for(; count < 100;)
        {
            std::unique_lock<std::mutex> locker(mu);
            cond.wait(locker,[](){ return (count%2 == 1); });
            std::cout << "From Odd:    " << count << std::endl;
            count++;
            locker.unlock();
            cond.notify_all();
        }
    
    }
    
    void PrintEven()
    {
        for(; count < 100;)
        {
            std::unique_lock<std::mutex> locker(mu);
            cond.wait(locker,[](){ return (count%2 == 0); });
            std::cout << "From Even: " << count << std::endl;
            count++;
            locker.unlock();
            cond.notify_all();
        }
    }
    
    int main()
    {
        std::thread t1(PrintOdd);
        std::thread t2(PrintEven);
        t1.join();
        t2.join();
        return 0;
    }
    
    0 讨论(0)
  • 2021-01-03 03:04

    Solution using condition variable.

    #include<iostream>
    #include<thread>
    #include<mutex>
    using namespace std;
    mutex oddevenMu;
    condition_variable condVar;
    int number = 1;
    
    void printEvenOdd(bool isEven, int maxnubmer)
    {
        unique_lock<mutex> ul(oddevenMu);
        while (number < maxnubmer)
        {
            condVar.wait(ul, [&]() {return number % 2 == isEven;});
            cout << number++ << " ";
            condVar.notify_all();
        }
    
    }
    
    int main(string args[])
    {
        thread oddThread(printEvenOdd, false, 100);
        thread evenThread(printEvenOdd, true, 100);
        oddThread.join();
        evenThread.join();
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题