又是某课程的实验(感觉好烦啊啊。。。),这次终于不用编译内核了,但是但是,他让我们写多线程。好吧,那就写写写,但是等等。。他要我们实现生产者-消费者同步问题,要用信号量解决同步问题。。这几个都是什么鬼。。好吧,不懂的自行google吧。
话不多说,直接上代码,目前只是简易实现,可能会有问题,大家可以指出啊,我虚心受教~~
windows线程
//包含必须头文件
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
//定义相关结构
#define BUFFER_SIZE 5
typedef int buffer_item;
//相关信号量的声明以及buffer的声明
HANDLE mutex ;
HANDLE empty,full;
buffer_item buffer[BUFFER_SIZE]={-1};
int count = 0;
//向buffer中插入元素函数
int insert_item(buffer_item item){
WaitForSingleObject(empty,INFINITE);
WaitForSingleObject(mutex,INFINITE);
int state = 0;
printf("now count is %d in insert\n",count);
if(buffer[count]!=-1)
state = 1;
else{
buffer[count] = item;
count = (count+1)%BUFFER_SIZE;
}
ReleaseMutex(mutex);
ReleaseSemaphore(full,1,NULL);
printf("now release in insert\n");
if(state)
return -1;
else
return 0;
}
//向buffer中删除元素函数
int remove_item(buffer_item *item){
WaitForSingleObject(full,INFINITE);
WaitForSingleObject(mutex,INFINITE);
int state = 0;
printf("now count is %d in remove\n",count);
if(count>0)
count = count-1;
else
count = 4;
if(buffer[count]!=-1){
buffer[count] = -1;
}
else
state = 1;
ReleaseMutex(mutex);
ReleaseSemaphore(empty,1,NULL);
printf("now release in remove\n");
if(state)
return -1;
else
return 0;
}
//生产者进程函数
void *producer(void *param){
buffer_item randb;
srand((unsigned)time(NULL));
while(TRUE){
randb = rand();
sleep(rand()%1000);
printf("now produce want to produce %d \n",randb);
if(insert_item(randb)){
printf("report error condition of producer\n");
}
else{
printf("producer produced %d\n",randb);
}
}
}
//消费者进程函数
void *consumer(void *param){
buffer_item randb;
sleep(1000);
srand((unsigned)time(NULL));
while(TRUE){
randb= rand();
sleep(rand()%1000);
printf("now consume want to consume %d \n",randb);
if(remove_item(&randb))
printf("report error condition of consume\n");
else
printf("consume consumed %d\n",randb);
}
}
//mian函数
int main(int argc,char *argv[])
{
mutex = CreateMutex(NULL,FALSE,NULL);
empty = CreateSemaphore(NULL,4,4,NULL);
full = CreateSemaphore(NULL,0,4,NULL);
DWORD ThreadIdOfConsumer;
DWORD ThreadIdOfProducer;
HANDLE ThreadHandleOfConsumer;
HANDLE ThreadHandleOfProducer;
int Param = 10;
ThreadHandleOfConsumer= CreateThread(
NULL,
0,
&consumer,
&Param,
0,
&ThreadIdOfConsumer);
ThreadHandleOfProducer= CreateThread(
NULL,
0,
&producer,
&Param,
0,
&ThreadIdOfProducer);
if(ThreadHandleOfConsumer!=NULL&&ThreadHandleOfProducer!=NULL){
sleep(5000);
TerminateThread(ThreadHandleOfConsumer,0);
TerminateThread(ThreadHandleOfProducer,0);
}
CloseHandle(ThreadHandleOfConsumer);
CloseHandle(ThreadHandleOfProducer);
system("pause");
return 0;
}
原谅我把全部写在一起了。。不过你们能懂就好啊
贴下结果:
Linux
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<semaphore.h>
#define BUFFER_SIZE 5
typedef int buffer_item;
pthread_mutex_t mutex ;
sem_t empty,full;
buffer_item buffer[BUFFER_SIZE]={-1,-1,-1,-1,-1};
int count = 0;
int insert_item(buffer_item item){
sem_wait(&empty);
pthread_mutex_lock(&mutex);
int state = 0;
printf("now count is %d in insert\n",count);
if(buffer[count]!=-1){
printf("error and buffer[count]==%d",buffer[count]);
state = 1;
}
else{
buffer[count] = item;
count = (count+1)%BUFFER_SIZE;
}
pthread_mutex_unlock(&mutex);
sem_post(&full);
printf("now release in insert\n");
if(state)
return -1;
else
return 0;
}
int remove_item(buffer_item *item){
sem_wait(&full);
pthread_mutex_lock(&mutex);
int state = 0;
printf("now count is %d in remove\n",count);
if(count>0)
count = count-1;
else
count = 4;
if(buffer[count]!=-1){
buffer[count] = -1;
}
else
state = 1;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
printf("now release in remove\n");
if(state)
return -1;
else
return 0;
}
void *producer(void *param){
buffer_item randb;
srand((unsigned)time(NULL));
while(1){
randb = rand();
sleep(rand()%2);
printf("now produce want to produce %d \n",randb);
if(insert_item(randb)){
printf("report error condition of producer\n\n");
}
else{
printf("producer produced %d\n\n",randb);
}
}
}
void *consumer(void *param){
buffer_item randb;
sleep(1);
srand((unsigned)time(NULL));
while(1){
randb= rand();
sleep(rand()%2);
printf("now consume want to consume %d \n",randb);
if(remove_item(&randb))
printf("report error condition of consume\n\n");
else
printf("consume consumed %d\n\n",randb);
}
}
int main(int argc,char *argv[])
{
printf("start\n");
pthread_mutex_init(&mutex,NULL);
sem_init(&empty,4,4);
sem_init(&full,0,4);
pthread_t ThreadIdOfConsumer;
pthread_t ThreadIdOfProducer;
pthread_attr_t ThreadHandleOfConsumer;
pthread_attr_t ThreadHandleOfProducer;
int Param = 10;
pthread_attr_init(&ThreadHandleOfConsumer);
pthread_attr_init(&ThreadHandleOfProducer);
pthread_create(&ThreadIdOfConsumer,&ThreadHandleOfConsumer,consumer,NULL);
pthread_create(&ThreadIdOfProducer,&ThreadHandleOfProducer,producer,NULL);
//pthread_join(ThreadIdOfConsumer,NULL);
//pthread_join(ThreadIdOfProducer,NULL);
sleep(5);
pthread_kill(ThreadIdOfConsumer,0);
pthread_kill(ThreadIdOfProducer,0);
return 0;
}
结果:
还有几张就不想贴了。可以自己运行试试
结语:
在这里向提示几个坑,以免大家跳入:
- 关于rand函数的使用,其实我真心不觉得那个很随机,虽然你用下srand取得的效果还能接受吧,但是记得用srand吧,不然只能说每次都一样的序列了。。
- 关于sleep函数的使用。windows下5000单位是毫秒,所以是5秒,刚开始没注意,直接copy到linux下,然后。。就没有然后了。。程序半天没有结果。。我还以为写错了呢。。后来发现原来linux下单位是秒,所以5000就是5000秒。。难怪我等不到结果。。
- 关于linux下程序的编译执行,后面要记得加上参数,具体参数见图,反正我不加编译时会报错,提示你semaphore里的很多函数没有定义之类的,加上就好了,这个也有可能是我这边自己的问题吧。
最后,假如有人要写类似的可以做个参考吧,那些线程啥的用封装好的用习惯了,刚开始用基层的真还有点不习惯呢。百忙花个时间来作个死。。你猜下次某课实验是啥~~