程序在单独的线程上打印奇数和偶数

我正在学习使用pthreads编程。 如何编写程序在单独的线程上打印奇数和偶数。

您需要两个同步对象,例如信号量或条件变量。 这个想法是线程A在打印之前请求信号量A并且在线程B执行相反操作之后释放信号量B.

这个想法是在线程A请求信号量A之后,它将信号量降为0.下次它请求信号量A它将阻塞直到线程B释放信号量。

在伪代码中,这看起来像:

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) 

既然你想教自己线程编程,我会留给你把它转换成实际的pthreads代码。

我认为使用条件变量和互斥量可以解决这个问题。


     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

    主要()
     {
        pthread_t thread1,thread2;

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

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

       出口(0);
     }

     //打印奇数

     void * functionCount1()
     {
       对于(;;)
        {

           //锁定互斥锁,然后等待信号重新启动互斥锁
           pthread_mutex_lock(&count_mutex);


           //检查最后一次发射的值是否为奇数; 如果是这样,请等待
           //打印出偶数
           if(count%2!= 0){
               pthread_cond_wait(&condition_var,&count_mutex);
           }

          计数++;
           printf(“计数器值functionCount1:%d \ n”,计数);
           pthread_cond_signal(&condition_var);

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


     //打印偶数
     void * functionCount2()
     {
       对于(;;)
        {

           //锁定互斥锁,然后等待信号重新启动互斥锁
           pthread_mutex_lock(&count_mutex);

           //检查最后一次发射的值是否为偶数; 如果是这样,请等待
           //打印一个奇数
           if(count%2 == 0){
               pthread_cond_wait(&condition_var,&count_mutex);
           }

          计数++;
           printf(“计数器值functionCount2:%d \ n”,计数);

           pthread_cond_signal(&condition_var);

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

    输出::
     ubuntu:〜/ work $ gcc even_odd.c -lpthread
     ubuntu:〜/ work $ ./a.out 
    计数器值functionCount1:1
    计数器值functionCount2:2
    计数器值functionCount1:3
    计数器值functionCount2:4
    计数器值functionCount1:5
    计数器值functionCount2:6
    计数器值functionCount1:7
    计数器值functionCount2:8
    计数器值functionCount1:9
    计数器值functionCount2:10
     ...

传递指示符值以指示线程是否应通过线程函数参数打印奇数或偶数。

根据相同的情况,从0(对于偶数)或1(对于奇数)开始,并在线程和打印中继续递增2。

您还可以打印线程ID以及数字,以指示哪个线程正在打印什么。

我假设你知道如何使用pthreads。

[更新]: pthreads的链接即使使用信号量或互斥量,你也很难按1,2,3等顺序获得输出,因为你永远不知道哪个线程有机会先执行。 为此,您可能必须使用一些高级概念,如线程优先级或使用条件变量的线程间通信。 这些只是提示。 我希望如果您浏览该链接,您将获得更多信息。

 #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; } 

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