printing odd and even number printing alternately using threads in C++
Asked Answered
H

18

5

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 semaphore. even semaphore initialized to 1 and odd initialized to 0.

**T1 thread function** 
funOdd()
{  
  wait(even)  
  print odd;  
  signal(odd)  
}


**T2 thread function**
funEven()  
{  
  wait(odd)  
  print even  
  signal(even)  
}  

In addition to this if my functions are generating only number and there is a third thread T3 which is going to print those numbers then what should be ideal design ? I used an array where odd number will be placed at odd place and even number will be place at even position. T3 will read from this array this will avoid any thread saftey over this array and if T3 does not find any index then it will wait till that index gets populated. Another solution can be to use a queue which will have a mutex which can be used by T1 and T2 while insertion.

Please comment on this solution and how can i make it more efficient.

Edit to make problem much clear: Overall problem is that I have two producers (T1,T2) and a single consumer (T3), and my producers are interdependent.

Hypha answered 1/2, 2013 at 6:48 Comment(5)
If you want serial behavior don't use threads.Understand
I can avoid thread in this case but this is very valid scenario where my 2 threads are dependent on each other.Hypha
I'm trying really hard to follow this question, and have discovered that without code (a near-universal language, save for unusual var names) the description is muddy to follow, and in some places near-impossible. It looks like you're have two producers (T1,T2) and a single consumer (T3), but your producers are interdependent. I'm also curious how "if T3 does not find any index then it will wait till that index gets populated." is going to hold up without synchronization of some kind. Finally, "very valid"? Valid is a bit. It is, or it isn't.Numidia
@Numidia T3 can sleep for some time and again check for this index. if index is populated then move to next else sleep again. Why do you think we need synchronization for array Can you explain me a scenario where I will require synchronization ?Hypha
does this question have any follow up? in the end, what is your own answer?Overhappy
C
8

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;
}
Cassy answered 12/6, 2018 at 8:55 Comment(6)
Wouldn't this lead to a deadlock if the t2 thread executes first? PrintEven() acquires the lock then waits for count to become even. But count is 1, and it will become even only when PrintOdd() executes count++. PrintOdd() is waiting for the lock, so cannot execute.Mccomb
@MaskedMan: No it'll not. That is what condition variable is doing. It releases the lock if the condition is not met and goes to sleep kind of mode. So if t2 acquires the lock first, then it will go into waiting state since coun%2 == 0 condition will fail. When t2 releases the lock, t1 thread can acquire the lock and it can execute. Once it finishes executing, it calls notify_all(), which will notify the t2 thread saying now you can check if the condition is met or not, If the condition is met, it re-acquires the lock and print the even number and the sequence continues.Hildegardehildesheim
There is a subtle bug in the program. The even thread may print 100 as last result even though we want the program to print values below 100 (see the condition count < 100).Petrochemistry
does locker.unlock(); required for unique_lock? isnt unlock automatically?Nival
@PravejKhan, unlock will happen only if the locker goes out of scope. In this case, since we are still in the loop, the lock will still be applied. That is why we need to unlock manually.Opaline
@Opaline what is the use of condition variables then? If I understand correctly, if the condition is failed, it will unlock automatically.Nival
P
3

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;
}
Phospholipide answered 4/12, 2019 at 11:59 Comment(0)
F
1
 #include  <stdio.h>
 #include  <stdlib.h>
 #include  <iostream>
 #include  <pthread.h>
 #include  <semaphore.h>

  sem_t sem;
  sem_t sem2;
  using namespace std ;

int count = 1;

void increment(int x)
{
    cout << "called by thread : " << x << "count is : " << count ++ << "\n";
}

void *printAltmessage1(void *thread_value)
{
    for(int m=0; m < (*(int *)thread_value); m++)
    {
        if (sem_wait(&sem) == 0)
        {
            cout << " Thread printAltmessage1 is executed" <<"\n";  
            increment(1);
            sem_post(&sem2);
        }
    }
}

void *printAltmessage2(void *thread_value)
{
    for(int m=0; m < (*(int *)thread_value); m++)
    {
        if (sem_wait(&sem2) == 0)
        {
            cout << " Thread printAltmessage2 is executed" <<"\n";
            increment(2);  
            sem_post(&sem);
        }
    }
}

int main()
{
     sem_init(&sem,0, 1);
     sem_init(&sem2,0, 0);
     pthread_t threads[2];
     int x =8;
     for(int i=0;i<2;i++)
     {
          if(i==0)
          int rc =pthread_create(&threads[i],NULL,printAltmessage1,(void*)&x);
          else
          int rc =pthread_create(&threads[i],NULL,printAltmessage2,(void*)&x);
      }
      pthread_exit(NULL);
      return 0;
}
Fabrienne answered 18/9, 2014 at 16:50 Comment(0)
T
1

This is the easiest solution you can refer:

#include<iostream>
#include<mutex>
#include<pthread.h>
#include<cstdlib>
int count=0;
using namespace std;
mutex m;
void* printEven(void *a)
{
   while(1)
   {
       m.lock();
       if(count%2==0)
       {
          cout<<" I am Even"<<count<<endl;
          count++;
       }
       if(count==100)
           break;
       m.unlock();
   }
}
void* printOdd(void *b)
{
    while(1)
    {
       m.lock();
       if(count%2!=0)
       {
           cout<<"I am odd"<<count<<endl;
           count++;
       }
       if(count>100)
          break;
       m.unlock();
    }
 }
 int main()
 {
     int *ptr = new int();
     pthread_t thread1, thread2;
     pthread_attr_t attr;
     pthread_attr_init(&attr);
     pthread_create(&thread1,&attr,&printEven,NULL);
     pthread_create(&thread2,&attr,&printOdd, NULL);
     pthread_join(thread1,&ptr);
     pthread_join(thread2,&ptr);
     delete ptr;
 }
Thereby answered 20/10, 2018 at 14:46 Comment(1)
There is a mismatch between the allocation deallocation of ptr. free(ptr) should be changed to delete ptr.Penniepenniless
T
1

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;
}
Tensor answered 21/10, 2019 at 17:16 Comment(0)
S
1
    #include <iostream>
    #include <thread>
    #include <mutex> 
    using namespace std;

    std::mutex m;
    int count = 0;

    void printEven()
    {
        cout << "Entered Even\n" << endl;
        while(count <= 10)
        {
            m.lock();
            if(count%2 == 0)
                cout << count++ << " ";
             m.unlock();
        }
    }
    
    void printOdd()
    {
        cout << "Entered Odd" << endl;
        while(count < 10)
        {
             m.lock();
            if(count%2 == 1)
                cout << count++ << " ";
             m.unlock();
        }
    }

    int main()
    {
       std::thread t1(printOdd);
       std::thread t2(printEven);
       t1.join();
       t2.join();
        return 0;
    }
Seer answered 27/5, 2021 at 7:21 Comment(3)
The Simplest one with only Mutex & without using Conditional variable :)Seer
How do you manage to print 1 if even thread called 1st? how will you maintain the right sequence?Nival
This is simple but really inefficient logic because each thread wastes too many CPU cycles instead of making threads wait until the other one completes.Ghent
N
1
#include "threadFunc.hpp"
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;

mutex t1;
condition_variable cond;


int number = 11;
int count = 0;

void printEven()
{
    while(1)
    {
        unique_lock<mutex> ul(t1);
        if(count< number)
        {
            if(count % 2 != 0)
            {
                cond.wait(ul);
            }

            cout<<count<<" : printed by thread"<<this_thread::get_id()<<endl;
            count++;
        }
        if(count > number)
            break;

        ul.unlock();
        cond.notify_all();
    }

}

void printOdd()
{
    while(1)
    {
        unique_lock<mutex> ul(t1);
        if(count< number)
        {
            if(count % 2 == 0)
            {
                cond.wait(ul);
            }

            cout<<count<<" : printed by thread"<<this_thread::get_id()<<endl;
            count++;
        }
        if(count > number)
            break;

        ul.unlock();
        cond.notify_all();
    }

}
Nameless answered 13/11, 2021 at 12:39 Comment(0)
O
0

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));
  }
}
Overhappy answered 1/2, 2013 at 7:32 Comment(1)
@J99 more or less Java. Language is irrelevant, the behind it does not changeOverhappy
H
0

As a first thing, the two functions should a least contain a loop, (unless you just want a single number)

A more standard solution (which remaps your idea) is to have a global structure containing a a mutex, and two condition variables (odd and even) plus a return value, and another condition for the printing. than use a uique_lock to handle the synchronization.

IN PSEUDOCODE:

struct global_t
{
    mutex mtx;
    int value = {0};
    condition_variable be_odd, be_even, print_it;
    bool bye = {false};

    global_t() { be_odd.notify(); }
} global;

void odd_generator()
{
    int my_odd = 1;
    for(;;)
    {
        unique_lock lock(global.mtx);
        if(global.bye) return;
        global.be_odd.wait(lock);
        global_value = my_odd; my_odd+=2;
        global.print_it.notify();
        if(my_odd > 100) bye=true;
    } //let RAII to manage wait states and unlocking
};

void even_generator()
{ /* same as odd, with inverted roles */ }

void printer()
{
    for(;;)
    {
        unique_lock lock(global.mtx);
        if(bye) return;
        global.ptint_it.wait(lock);
        std::cout << global.value << std::endl;
        ((global.value & 1)? global.be_even: global.be_odd).notify();
    }
}


int main()
{
    thread oddt(odd_generator), event(even_generator), printt(printer);
    oddt.join(), event.join(), printer.join();
}

Note that, apart didactic purpose, this solution adds no value respect to a simple loop printing the value of a counter, since there will never be real concurrency.

Note also (to avoid globals) that you can wrap everything into a class (making the actual main a class method) and instantate that class on the stack inside the new main.

Harbird answered 1/2, 2013 at 7:43 Comment(0)
E
0

Solution is based on C++11 critical code section aka mutex.

Here's the working code, followed by an explanation.

Tested and working on VS2013:

using namespace std;
#include <iostream>
#include <string>
#include <thread>
#include <mutex>

std::mutex mtx;

void oddAndEven(int n, int end);

int main()
{
std::thread odd(oddAndEven, 1, 10);
std::thread Even(oddAndEven, 2, 10);

odd.join();
Even.join();

return 0;
}



void oddAndEven(int n, int end){
int x = n;
for (; x < end;){
    mtx.lock();
    std::cout << n << " - " << x << endl;
    x += 2;
    mtx.unlock();
    std::this_thread::yield();
    continue;
 }
}

i.e:

Thread odd goes to method oddAndEven with starting number 1 thus he is the odd. He is the first to acquire the lock which is the mtx.lock().

Meanwhile, thread Even tries to acquire the lock too but thread odd acquired it first so thread Even waits.

Back to thread odd (which has the lock), he prints the number 1 and releases the lock with mtx.unlock(). At this moment, we want thread Even to acquire lock and to print 2 so we notify thread Even by writing std::this_thread::yield(). Then thread Even does the same.

etc etc etc.

Exigent answered 15/5, 2015 at 19:25 Comment(3)
What if one of the threads takes more time than the other? I mean if you add inside the lock sleep_for(rnd_number) than the order in which it prints might be reversed. I guess one have to use condition_variableHorology
Just came across this.What if yield does not do anything, I mean the same thread is scheduled again.Then the order would change.One might get 0 2 4 1 3...Scherle
Hey @GauravSehgal, I am sorry but I didn't understand what you meant. If you think there's a mistake you can edit the answer though..Exigent
O
0
#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;
}
Olshausen answered 7/9, 2019 at 19:1 Comment(0)
E
0

This code will work . I have tested it on visual studio 2017

#include "stdafx.h"
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
using namespace std;
mutex m;
condition_variable cv;
int num = 1;


void oddThread() {​​​​​​​
    
    for (; num < 10;) {​​​​​​​
        unique_lock<mutex> lg(m);
        cv.wait(lg, [] {​​​​​​​return (num % 2 ==1); }​​​​​​​);
        cout << "From odd Thread " << num << endl;
        num++;
        lg.unlock();
        cv.notify_one();
    }​​​​​​​
}​​​​​​​
void evenThread() {​​​​​​​
    for (; num < 100;) {​​​​​​​
        unique_lock<mutex> lg(m);
        cv.wait(lg, [] {​​​​​​​return (num % 2 == 0); }​​​​​​​);
        cout << "From even Thread " << num << endl;
        num++;
        lg.unlock();
        cv.notify_one();
    }​​​​​​​
}​​​​​​​


int main() {​​​​​​​
    
    thread t1{​​​​​​​ oddThread}​​​​​​​; //odd function thread
    thread t2{​​​​​​​ evenThread}​​​​​​​;
    t1.join();
    t2.join();
    cin.get();
    return 0;
}​​​​​​​

output

from oddThread: 1 from evenThread: 2 from oddThread: 3 from evenThread: 4 from oddThread: 5 from evenThread: 6 from oddThread: 7 from evenThread: 8 from oddThread: 9 from evenThread: 10

Electrophone answered 22/6, 2021 at 15:42 Comment(0)
E
0
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
std::mutex m;
std::condition_variable cv;
int counter =1;

void printEven()
{
    std::unique_lock<std::mutex> lk(m);
    while(1)
    {
        if(counter > 10)
            break;
        if(counter %2 != 0)
        {
            cv.wait (lk);
        }
        else
        {
            cout << "counter : " << counter << endl;
            counter++;
            //lk.unlock();
            cv.notify_one();
        }
    
    
    }
}


void printOdd()
{
    std::unique_lock<std::mutex> lk(m);
    
    while(1)
    {
        if(counter > 9)
        break;
        if(counter %2 == 0)
        {
            cv.wait (lk);
        }
        else
        {
            cout << "counter : " << counter << endl;
            counter++;
            //lk.unlock();
            cv.notify_one();
        }
    
    
    }
}

int main()
{
    std::thread t1(printEven);
    std::thread t2(printOdd);
    t1.join();
    t2.join();
    cout << "Main Ends" << endl;
}
Embolus answered 14/7, 2021 at 15:44 Comment(0)
K
0

i have used anonymous func (lambda) to do this and clubbed cond variable and mutex.

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

using namespace std; 

int main() {
    int count = 1;
    mutex mtx;
    condition_variable condition;
    const int ITERATIONS = 20; // iterations

    //prints odd numbers
    thread t1([&]() {
        while (count < ITERATIONS)
        {
            unique_lock <mutex> lock(mtx);
            condition.wait(lock, [&]() {
                return count % 2 != 0;
                });

            cout << "thread1 prints: " << count << endl;
            count++;
            lock.unlock();
            condition.notify_all();
        }
    });
    
    thread t2([&]
        {
            while (count < ITERATIONS)
            {
                unique_lock <mutex> lock(mtx);
                condition.wait(lock, [&]() {
                    return count % 2 == 0;
                    });
                cout << "thread2 prints: " << count << endl;
                count++;
                lock.unlock();
                condition.notify_all();
            }
        });

    t1.join();
    t2.join();
 }
Kismet answered 27/8, 2021 at 16:13 Comment(0)
I
0
#include <bits/stdc++.h>
#include <stdlib.h>
#include <unistd.h>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;

mutex m;
condition_variable cv;
unique_lock<mutex> lck(m);

void *printeven(void *arg)
{
    int *n = (int *)arg;
    while (*n <= 100)
    {
        cv.wait(lck);
        *n = *((int *)arg);
        cout << this_thread::get_id() << " : " << *n << endl;
        *n = *n + 1;
        cv.notify_one();
    }
    exit(0);
}

void *printodd(void *arg)
{
    int *n = (int *)arg;
    while (*n <= 100)
    {
        *n = *((int *)arg);
        cout << this_thread::get_id() << " : " << *n << endl;
        *n = *n + 1;
        cv.notify_one();
        cv.wait(lck);
    }
    exit(0);
}

int main()
{
    int num = 1;
    pthread_t p1 = 1;
    pthread_t p2 = 2;

    pthread_create(&p1, NULL, printodd, &num);
    pthread_create(&p2, NULL, printeven, &num);

    pthread_join(p1, NULL);
    pthread_join(p2, NULL);
    return 0;
}
Iron answered 17/11, 2021 at 13:57 Comment(2)
See: Why should I not #include <bits/stdc++.h>?Peppergrass
It would be great to have some explanation in your answer about what your code does and how it solves the question.Gene
S
0
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx;
std::condition_variable even_to_odd;
std::condition_variable odd_to_even;
unsigned int count = 1;
constexpr int MAX_COUNT = 20;

void even(int n) {
    for (int i = n; i <= MAX_COUNT; i++) {
        std::unique_lock<std::mutex> lock(mtx);
        if (i %2 == 0) {
            odd_to_even.wait(lock);
            std::cout << "Even: " << i << std::endl;
            even_to_odd.notify_one();
        }
    }
}

void odd(int n) {
    for (int i = n; i <= MAX_COUNT; i++) {
        std::unique_lock<std::mutex> lock(mtx);
        if (i == 1) {
            std::cout << "Odd : " << i << std::endl;
            odd_to_even.notify_one();
        }
        else if (i % 2 != 0) {
            even_to_odd.wait(lock);
            std::cout << "Odd : " << i << std::endl;
            odd_to_even.notify_one();
        }
    }
}

int main() {
    std::thread thread1(even,count);
    std::thread thread2(odd,count);

    thread1.join();
    thread2.join();
    return 0;
}
Soledadsolely answered 24/11, 2021 at 8:33 Comment(0)
S
0

This is how I solve it using current c++ standard (practically using c++11).
There is no need to check in which thread we are, nor to check if the number is currently odd or even. The control is passed between the threads after each increment. Note that there will be no deadlock:
A notify happens before wait, and they both are under the lock. Hence when a waiting thread gives the other thread a chance to lock, the other thread will reach notify before reaching its own wait.
Note also that a thread being notified might block if the notifying thread has not yet started waiting. But this block is only momentarily and has no influence on the threads taking each its own turn to do the printing and increment.

#include <iostream>
#include <thread>
#include <mutex>
#include <future>

using namespace std;

mutex mtx;
condition_variable cv;
int counter = 1; 

void printNumbers(int threadId) {
    while (true) {
        unique_lock<mutex> lock(mtx);
        cout << "Thread " << threadId << ": " << counter << endl;
        counter++;
        cv.notify_all(); 
        cv.wait(lock); 
    }
}

int main() {
    thread thread1(printNumbers, 1); 
    thread thread2(printNumbers, 2); 

    thread1.join(); 
    thread2.join(); 

    return 0;
}

The above code is a solution. However, it is undetermined which of the threads will be counting the odd numbers and which will be counting the even numbers.
It will be incorrect to try to solve it by switching the order of wait-notify for the thread of the even numbers. Doing that will not guarantee anymore that there will be no deadlock:
When a waiting thread gives the other a chance to lock, the other will reach its own wait without first notifying.

If we want thread 1 to be the one printing the odd numbers, a less elegant solution would be to add a simple condition as follows:

void printNumbers(int threadId) {
    while (true) {
        if (counter == 1 && threadId != 1 ) 
            continue; 
        unique_lock<mutex> lock(mtx);
        cout << "Thread " << threadId << ": " << counter << endl;
        counter++;
        cv.notify_all(); 
        cv.wait(lock); 
    }
}

I call it less elegant because this means that as long as the other thread did not start, the loop is busy-waiting.
So we will simply wait if we are in thread 2 and counter is still 1.
Note that the only situation of actually waiting there is when counter was 1 when locking, thus it is guaranteed that thread 1 is not waiting, and will notify.

void printNumbers(int threadId) {
    if (threadId == 2) {
        unique_lock<mutex> lock(mtx);
        if (counter == 1)
            cv.wait(lock);
    }

    while (true) {
        unique_lock<mutex> lock(mtx);
        cout << "Thread " << threadId << ": " << counter << endl;
        counter++;
        cv.notify_all(); 
        cv.wait(lock); 
    }
}
Sturtevant answered 23/2, 2024 at 14:2 Comment(0)
P
-2

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.

Pickax answered 29/4, 2013 at 6:10 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.