Program for printing odd numbers and even numbers in separate streams

I am learning programming with pthreads. How to write a program to print odd numbers and even numbers in separate streams.

+5
source share
6 answers

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

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

In pseudo code, it looks like this:

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 thread programming, I will leave it to you to convert this to real pthreads code.

+8
source

I think using a conditional variable and a mutex can 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
     ...

+3
source

Pass the value of the indicator to indicate whether the stream should print an odd number or even a number through the stream function argument.

Depending on whether you start with 0 (for even numbers) or 1 (for odd numbers) and continue to increase by 2 both in streams and when printing. A.

You can also print the stream identifier along with the number to indicate which stream prints what.

I assume you know how to use pthreads.

[Refresh]: Link for pthreads Even with semaphores or mutexes, it’s difficult for you to get a result of 1,2,3, etc., since you never know which thread will be able to execute in the first place. To do this, you may need to use some advanced concepts, such as thread priority or cross-threading using conditional variables. These are just hints. I hope that if you follow the link, you will get more information.

+1
source
 #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; } 
0
source

Logically, you can control the use of the flag (printOdd) with a variable (value) constantly increasing when printing every time.

Using lambda 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 conclusion is as follows.

enter image description here

0
source

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(); } } -------- 
-1
source

Source: https://habr.com/ru/post/1308436/


All Articles