我正在学习使用pthreads编程。 如何编写程序在单独的线程上打印奇数和偶数。
答案 0 :(得分:8)
您需要两个同步对象,例如信号量或条件变量。这个想法是线程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代码。
答案 1 :(得分:3)
我认为使用条件变量和互斥量可以解决这个问题。
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 ...
答案 2 :(得分:1)
传递一个指示器值,指示线程是否应该通过线程函数参数打印奇数或偶数。
根据相同的不同,从0(对于偶数)或1(对于奇数)开始,并在两个线程和打印中继续递增2.
您还可以打印线程ID以及数字,以指示哪个线程正在打印什么。
我假设你知道如何使用pthreads。
[更新]:pthreads的链接 即使使用信号量或互斥量,您也很难按1,2,3等顺序获取输出,因为您永远不知道哪个线程有机会先执行。为此,您可能必须使用一些高级概念,如线程优先级或使用条件变量的线程间通信。这些只是提示。我希望你通过链接获得更多信息。
答案 3 :(得分:0)
#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;
}
答案 4 :(得分:0)
从逻辑上讲,您可以使用标记(printOdd)进行控制,该标记的变量(值)每次打印时都会不断增加。
在Java 8中使用lambda,
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();
}
}
输出如下。
答案 5 :(得分:-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();
}
}
--------