本文最初发表于SpriteLW的博客http://blog.csdn.net/SpriteLW,欢迎转载,但请务必保留原文完整,并保留本声明。
今天翻了一下自己以前写的程序,发现以一个很有趣的代码―――用宏来写的多线程序程序。那是我女朋友的作业,用PV操作实现“生产者消费者”程序,她的老师说不能使用库,当时我的第一个想法是“怎么可能呢”。但为了在女朋友面前展示我的魅力,我答应了她帮她做。
当时正处C发旺期,,而且在女朋友的影响下更发挥了小宇宙,于是就想到了用宏,以下是整个代码:
#include
<
stdlib.h
>
#include < process.h >
#include < windows.h >
#include < iostream >
#include < time.h >
using namespace std;
#define PRODUCER 0
#define CONSUMER 1
int empty = 1 ;
int full = 0 ;
int who;
#define P(X)
{
X -- ;
switch (who)
{
case PRODUCER:
if (X < 0 )
{
cout << " Producer is waiting " << endl;
X = 0 ;
goto WAIT;
}
break ;
case CONSUMER:
if (X < 0 )
{
cout << " Consumer is waiting " << endl;
X = 0 ;
goto WAIT;
}
break ;
}
}
#define V(X)
{
X ++ ;
switch (who)
{
case PRODUCER:
goto LEAVE;
break ;
case CONSUMER:
goto LEAVE;
break ;
}
}
int buffer = 1 ;
void producer()
{
who = PRODUCER;
P(empty)
cout << " producer put a thing in the buffer " << endl;
buffer = 1 ;
V(full);
LEAVE:
return ;
WAIT:
return ;
}
void consumer()
{
who = CONSUMER;
P(full)
cout << " consumer get a thing in the buffer " << endl;
buffer = 0 ;
V(empty);
LEAVE:
return ;
WAIT:
return ;
}
int _tmain( int argc, _TCHAR * argv[])
{
srand((unsigned)time(NULL));
while ( 1 )
{
Sleep( 500 );
switch (rand() % 2 )
{
case 0 :
producer();
break ;
case 1 :
consumer();
break ;
}
}
return 0 ;
}
#include < process.h >
#include < windows.h >
#include < iostream >
#include < time.h >
using namespace std;
#define PRODUCER 0
#define CONSUMER 1
int empty = 1 ;
int full = 0 ;
int who;
#define P(X)
{
X -- ;
switch (who)
{
case PRODUCER:
if (X < 0 )
{
cout << " Producer is waiting " << endl;
X = 0 ;
goto WAIT;
}
break ;
case CONSUMER:
if (X < 0 )
{
cout << " Consumer is waiting " << endl;
X = 0 ;
goto WAIT;
}
break ;
}
}
#define V(X)
{
X ++ ;
switch (who)
{
case PRODUCER:
goto LEAVE;
break ;
case CONSUMER:
goto LEAVE;
break ;
}
}
int buffer = 1 ;
void producer()
{
who = PRODUCER;
P(empty)
cout << " producer put a thing in the buffer " << endl;
buffer = 1 ;
V(full);
LEAVE:
return ;
WAIT:
return ;
}
void consumer()
{
who = CONSUMER;
P(full)
cout << " consumer get a thing in the buffer " << endl;
buffer = 0 ;
V(empty);
LEAVE:
return ;
WAIT:
return ;
}
int _tmain( int argc, _TCHAR * argv[])
{
srand((unsigned)time(NULL));
while ( 1 )
{
Sleep( 500 );
switch (rand() % 2 )
{
case 0 :
producer();
break ;
case 1 :
consumer();
break ;
}
}
return 0 ;
}
相应地,我也给出了如果用库的代码:
#include
<
windows.h
>
#include < process.h >
#include < time.h >
using namespace std;
HANDLE full;
HANDLE empty;
void Producer( void * )
{
cout << " a Producer come in " << endl;
WaitForSingleObject(empty,INFINITE); // P(empty)
cout << " a Producer put a thing " << endl;
ReleaseSemaphore(full, 1 ,NULL); // V(full)
}
void Consumer( void * )
{
cout << " a Consumer come in " << endl;
WaitForSingleObject(full,INFINITE); // P(full)
cout << " a Consumer get a thing " << endl;
ReleaseSemaphore(empty, 1 ,NULL); // V(empty)
}
int _tmain( int argc, _TCHAR * argv[])
{
full = CreateSemaphore(NULL, 0 , 1 , " full " );
empty = CreateSemaphore(NULL, 1 , 1 , " emtpy " );
srand(time(NULL));
while ( 1 )
{
Sleep( 500 );
switch (rand() % 2 )
{
case 0 :
_beginthread(Producer, 0 ,NULL);
break ;
case 1 :
_beginthread(Consumer, 0 ,NULL);
break ;
default :
break ;
}
}
return 0 ;
}
#include < process.h >
#include < time.h >
using namespace std;
HANDLE full;
HANDLE empty;
void Producer( void * )
{
cout << " a Producer come in " << endl;
WaitForSingleObject(empty,INFINITE); // P(empty)
cout << " a Producer put a thing " << endl;
ReleaseSemaphore(full, 1 ,NULL); // V(full)
}
void Consumer( void * )
{
cout << " a Consumer come in " << endl;
WaitForSingleObject(full,INFINITE); // P(full)
cout << " a Consumer get a thing " << endl;
ReleaseSemaphore(empty, 1 ,NULL); // V(empty)
}
int _tmain( int argc, _TCHAR * argv[])
{
full = CreateSemaphore(NULL, 0 , 1 , " full " );
empty = CreateSemaphore(NULL, 1 , 1 , " emtpy " );
srand(time(NULL));
while ( 1 )
{
Sleep( 500 );
switch (rand() % 2 )
{
case 0 :
_beginthread(Producer, 0 ,NULL);
break ;
case 1 :
_beginthread(Consumer, 0 ,NULL);
break ;
default :
break ;
}
}
return 0 ;
}
上面的代码可能把老师搞蒙了,简简单单的PV操作竟被做成100行,当时我没有请教过人,也没有问过她的老师对不对,是否有更简单的方法,但因为那不是我的作业,于是就不了了之了。
总评:虽然能实现PV操作,但代码根本不能重用,与其说是PV操作,不如说是专为消费者生产者的PV操作。