开发者

program to print odd numbers and even numbers on seperate threads

I am learning 开发者_开发百科programming using pthreads. How can I write a program to print odd numbers and even numbers on separate threads.


You need two synchronization objects such as a semaphore or a condition variable. The idea is that thread A requests semaphore A before it prints and releases semaphore B after while thread B does the opposite.

The idea is that after thread A requests semaphore A, it will drop the semaphore to 0. The next time it requests semaphore A it will block until thread B releases the semaphore.

In pseudo code, this looks like:

initialization:
    // set semA to 1 so that the call to sem_wait in the
    // even thread will succeed right away
    sem_init(semA, 1)
    sem_init(semB, 0)

even_thread:
   to_print = 0;

   loop:
       sem_wait(semA);

       write(to_print);
       to_print += 2

       sem_post(semB)

odd_thread:
    to_print = 1

    loop:
        sem_wait(semB)

        write(to_print)
        to_print += 2

        sem_post(semA)

Since you want to teach yourself threads programming, I'll leave it to you to convert this into actual pthreads code.


I think using a conditional variable and a mutex could solve this problem.


    pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t  condition_var   = PTHREAD_COND_INITIALIZER;

    void *functionCount1();
    void *functionCount2();

    int  count = 0;
    #define COUNT_DONE  200

    main()
    {
       pthread_t thread1, thread2;

       pthread_create( &thread1, NULL, &functionCount1, NULL);
       pthread_create( &thread2, NULL, &functionCount2, NULL);

       pthread_join( thread1, NULL);
       pthread_join( thread2, NULL);

       exit(0);
    }

    // Print odd numbers

    void *functionCount1()
    {
       for(;;)
       {

          // Lock mutex and then wait for signal to relase mutex
          pthread_mutex_lock( &count_mutex );


          // Check if the last emitted value was an odd; if so, wait till
          // an even is printed
          if (count % 2 != 0) {
              pthread_cond_wait( &condition_var, &count_mutex );
          }

          count++;
          printf("Counter value functionCount1: %d\n",count);
          pthread_cond_signal( &condition_var );

          if(count >= COUNT_DONE) {
             pthread_mutex_unlock( &count_mutex );
             return(NULL);
          }
          pthread_mutex_unlock( &count_mutex );
        }
    }


    // print even numbers
    void *functionCount2()
    {
       for(;;)
       {

          // Lock mutex and then wait for signal to relase mutex
          pthread_mutex_lock( &count_mutex );

          // Check if the last emitted value was an even; if so, wait till
          // an odd is printed
          if (count % 2 == 0) {
              pthread_cond_wait( &condition_var, &count_mutex );
          }

          count++;
          printf("Counter value functionCount2: %d\n",count);

          pthread_cond_signal( &condition_var );

          if(count >= COUNT_DONE) {
             pthread_mutex_unlock( &count_mutex );
             return(NULL);
          }
          pthread_mutex_unlock( &count_mutex );
        }
    }

    Output::
    ubuntu:~/work$ gcc even_odd.c -lpthread
    ubuntu:~/work$ ./a.out 
    Counter value functionCount1: 1
    Counter value functionCount2: 2
    Counter value functionCount1: 3
    Counter value functionCount2: 4
    Counter value functionCount1: 5
    Counter value functionCount2: 6
    Counter value functionCount1: 7
    Counter value functionCount2: 8
    Counter value functionCount1: 9
    Counter value functionCount2: 10
    ...


Pass an indicator value to indicate if the thread should be printing odd number or even number through the thread function argument.

Depending upon the same, start from 0 (for even numbers) or 1 (for odd numbers) and keep incrementing by 2 in both the threads and print.

You can also print the thread-id along with the number to indicate which thread is printing what.

I assume you know how to use pthreads.

[Update]: Link for pthreads Even with the use of semaphores or mutex, it is difficult for you to get the output in order of 1,2,3 etc as you never know which thread will get the chance to execute first. For this, you may have to use some advanced concepts like thread priority or Inter-thread communication using conditional variables. These are just hints. I hope if you go through the link you will get more information.


#include "stdafx.h"
#include "TestC.h"
#include"afxmt.h "

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;

CEvent myEvent1;
CEvent myEvent2;

UINT PrintEven(LPVOID pParam)
{
    int nNum = 2;
    while( nNum  < 20 )
    {
        myEvent2.Lock();
        CString str;
        str.Format("%d\n",nNum);
        printf(str);
        nNum += 2;
        myEvent1.SetEvent();
    }
  return 1;
}

UINT PrintOdd(LPVOID pParam)
{
    int nNum = 1;
    while( nNum  < 20 )
    {
        //myEvent1.Lock();
        CString str;
        str.Format("%d\n",nNum);
        printf(str);
        nNum += 2;
        myEvent2.SetEvent();
        myEvent1.Lock();
    }
  return 1;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    AfxBeginThread(PrintOdd, 0);
    AfxBeginThread(PrintEven, 0);
    Sleep( 1000 );
    return 1;
}


Logically, you can control using a flag ( printOdd ) with a variable (value) constantly incremented on printing each time.

Using lambda's in java 8,

public class OddEvenThreads {

final int limit = 20; // constant
static volatile int value = 1;
static volatile boolean printOdd = true;

public static void main(String[] args) {

    new Thread(() -> {
        while (value < limit) {
            if (!printOdd && (value % 2) == 0) {
                System.out.println("Even Thread :  " + value++);
                printOdd = !printOdd;
            }
        }
    }).start();

    new Thread(() -> {
        while (value < limit) {
            if (printOdd && (value % 2) != 0) {
                System.out.println("Odd Thread :  " + value++);
                printOdd = !printOdd;
            }
        }
    }).start();

}

}

The output is as follows.

program to print odd numbers and even numbers on seperate threads


In JAVA ...

public class EvenOddGenTest {

/**
* @param args
*/
public static void main(String[] args) {

NumberGenerator numGenerator = new NumberGenerator();

OddGenerator oddGen = new OddGenerator(numGenerator);
EvenGenerator evenGen = new EvenGenerator(numGenerator);

oddGen.start();
evenGen.start();

}

}
------------------

public class OddGenerator extends Thread {

public NumberGenerator numGen;

public OddGenerator(NumberGenerator numberGen) {
this.numGen = numberGen;
}

public void run() {
int i = 1;
while (i <= 9) {

numGen.printOdd(i);
i = i + 2;
}
}

}

----

public class EvenGenerator extends Thread {

public NumberGenerator numGen;

public EvenGenerator(NumberGenerator numberGen) {
this.numGen = numberGen;
}

public void run() {
int i = 2;
while (i <= 10) {
numGen.printEven(i);
i = i + 2;
}
}
}
------


public class NumberGenerator {

boolean oddPrinted = false;

public synchronized void printOdd(int number) {

while (oddPrinted == true) {
try {
wait();

} catch (InterruptedException e) {

}
}

System.out.println("NumberGenerator.printOdd() " + number);
oddPrinted = true;
notifyAll();

}

public synchronized void printEven(int number) {
while (oddPrinted == false) {
try {
wait();

} catch (InterruptedException e) {

}
}

oddPrinted = false;
System.out.println("NumberGenerator.printEven() " + number);
notifyAll();
}
}

-------- 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜