生产者-消费者问题编程简单实现--windows和linux下

792 查看

又是某课程的实验(感觉好烦啊啊。。。),这次终于不用编译内核了,但是但是,他让我们写多线程。好吧,那就写写写,但是等等。。他要我们实现生产者-消费者同步问题,要用信号量解决同步问题。。这几个都是什么鬼。。好吧,不懂的自行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里的很多函数没有定义之类的,加上就好了,这个也有可能是我这边自己的问题吧。

最后,假如有人要写类似的可以做个参考吧,那些线程啥的用封装好的用习惯了,刚开始用基层的真还有点不习惯呢。百忙花个时间来作个死。。你猜下次某课实验是啥~~