生产者使用者线程同步

时间:2018-08-09 03:47:24

标签: c++ linux multithreading pthreads producer-consumer

在HP采访中有人问我一个问题。 有1个缓冲区,有1个生产者线程和2个使用者线程。您将如何同步?我的答案是

struct Node
{
    int data;
    Node * next;
    Node * lastPrev;
}*buffer;

sem_t semaphore,sem2;
pthread_mutex_t lock,mut;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

int global=0;

void writeToBuffer(int i)
{

    if(!buffer)
    {
        buffer= new Node;
        buffer->next=0;
        buffer->data=i;
        buffer->lastPrev=0;
    }
    else
    {
        if(buffer && !buffer->lastPrev)
        {
            buffer->next=new Node;
            buffer->lastPrev=buffer;
            buffer->lastPrev->next->next=0;
            buffer->lastPrev->next->data=i; 
        }
        else
        {
            buffer->lastPrev->next->next=new Node;
            buffer->lastPrev= buffer->lastPrev->next;
            buffer->lastPrev->next->next =0;
            buffer->lastPrev->next->data=i; 
        }
    }
}

void printBuffer()
{
    for(Node*temp=buffer;temp!=0;temp=temp->next)
    {
        cout<<temp->data<<"-";
    }
    cout<<endl<<"##############################################"<<endl;
}

Node* getBufferFront()
{
    if(buffer==0)
    {
        return 0;
    }
    else
    {
        Node*temp = buffer;
        buffer=buffer->next;
        if(buffer && buffer->next && !buffer->next->next)
        {
            buffer->lastPrev=buffer;
        }
        else if(buffer && !buffer->next)
        {
            buffer->lastPrev=0;
        }
        return temp;
    }
}

void* producer(void * arg)
{
    int i=0;
    cout<<"entered producer"<<endl;
    while(i++!=15)
    {
        //cout<<i<<"-";
        pthread_mutex_lock(&lock);
        writeToBuffer(i);
        pthread_mutex_unlock(&lock);
        printBuffer();
        sem_post(&semaphore);
    }
    cout<<endl;
}

void* consumer1(void * arg)
{
    while(1)
    {

            sem_wait(&semaphore);
            pthread_mutex_lock(&lock);
            Node* temp = getBufferFront();
            pthread_mutex_unlock(&lock);  
            if(temp)
                cout<<"data consumed by consumer1="<<temp->data<<endl;
            else cout<<"NULL"<<endl;
            printBuffer();
            delete(temp);

    }

}

void* consumer2(void* arg)
{

    while(1)
    {

            sem_wait(&semaphore);
            pthread_mutex_lock(&lock);
            Node* temp = getBufferFront();
            pthread_mutex_unlock(&lock);  
            if(temp)
                cout<<"data consumed by consumer2="<<temp->data<<endl;
            else cout<<"NULL"<<endl;
            printBuffer();
            delete(temp);


    }
}

int main()
{
    pthread_t  th1,th2,th3;


    sem_init(&semaphore,0,0);

    if (pthread_mutex_init(&lock, NULL) != 0)
    {
        cout<<" mutex init has failed"<<endl;
        return 1;
    }


    buffer=0;


    pthread_create(&th1,0,producer,0);
    pthread_create(&th2,0,consumer1,0);
    pthread_create(&th3,0,consumer2,0);
    pthread_join(th1,0);
    pthread_join(th2,0);
    pthread_join(th3,0);
}

然后他告诉它不会平衡负载。您必须将任务平均分配给它们。我建议使用条件变量。就像这个->

struct Node
{
    int data;
    Node * next;
    Node * lastPrev;
}*buffer;

sem_t semaphore,sem2;
pthread_mutex_t lock,mut;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

int global=0;

void writeToBuffer(int i)
{

    if(!buffer)
    {
        buffer= new Node;
        buffer->next=0;
        buffer->data=i;
        buffer->lastPrev=0;
    }
    else
    {
        if(buffer && !buffer->lastPrev)
        {
            buffer->next=new Node;
            buffer->lastPrev=buffer;
            buffer->lastPrev->next->next=0;
            buffer->lastPrev->next->data=i; 
        }
        else
        {
            buffer->lastPrev->next->next=new Node;
            buffer->lastPrev= buffer->lastPrev->next;
            buffer->lastPrev->next->next =0;
            buffer->lastPrev->next->data=i; 
        }
    }
}

void printBuffer()
{
    for(Node*temp=buffer;temp!=0;temp=temp->next)
    {
        cout<<temp->data<<"-";
    }
    cout<<endl<<"##############################################"<<endl;
}

Node* getBufferFront()
{
    if(buffer==0)
    {
        return 0;
    }
    else
    {
        Node*temp = buffer;
        buffer=buffer->next;
        if(buffer && buffer->next && !buffer->next->next)
        {
            buffer->lastPrev=buffer;
        }
        else if(buffer && !buffer->next)
        {
            buffer->lastPrev=0;
        }
        return temp;
    }
}

void* producer(void * arg)
{
    int i=0;
    cout<<"entered producer"<<endl;
    while(i++!=15)
    {
        //cout<<i<<"-";
        pthread_mutex_lock(&lock);
        writeToBuffer(i);
        pthread_mutex_unlock(&lock);
        printBuffer();
        sem_post(&semaphore);
    }
    cout<<endl;
}

void* consumer1(void * arg)
{
    while(1)
    {
        pthread_mutex_lock(&mut);
        if(global%2==0)
        {
            sem_wait(&semaphore);
            pthread_mutex_lock(&lock);
            Node* temp = getBufferFront();
            pthread_mutex_unlock(&lock);  
            if(temp)
                cout<<"data consumed by consumer1="<<temp->data<<endl;
            else cout<<"NULL"<<endl;
            printBuffer();
            delete(temp);
            cout<<"global="<<global<<endl;  
            global++;
            pthread_cond_signal(&cond);
        }
        else
        {
            pthread_cond_wait(&cond,&mut);
        }
        pthread_mutex_unlock(&mut);
    }

}

void* consumer2(void* arg)
{

    while(1)
    {
        pthread_mutex_lock(&mut);
        if(global%2==1)
        {
            sem_wait(&semaphore);
            pthread_mutex_lock(&lock);
            Node* temp = getBufferFront();
            pthread_mutex_unlock(&lock);  
            if(temp)
                cout<<"data consumed by consumer2="<<temp->data<<endl;
            else cout<<"NULL"<<endl;
            printBuffer();
            delete(temp);
            cout<<"global="<<global<<endl;  
            global++;
            pthread_cond_signal(&cond);
        }
        else
        {
            pthread_cond_wait(&cond,&mut);
        }
        pthread_mutex_unlock(&mut);
    }
}

int main()
{
    pthread_t  th1,th2,th3;


    sem_init(&semaphore,0,0);
    sem_init(&sem2,0,0);
    if (pthread_mutex_init(&mut, NULL) != 0)
    {
        cout<<" mutex init has failed"<<endl;
        return 1;
    }
    if (pthread_mutex_init(&lock, NULL) != 0)
    {
        cout<<" mutex init has failed"<<endl;
        return 1;
    }


    buffer=0;


    pthread_create(&th1,0,producer,0);
    pthread_create(&th2,0,consumer1,0);
    pthread_create(&th3,0,consumer2,0);
    pthread_join(th1,0);
    pthread_join(th2,0);
    pthread_join(th3,0);
}

他告诉您只需使用一种同步技术。我不知道该怎么办。我与后来的测试。 1st在转移到消费者之前完成所有生产者工作。但是,消费者接连进行这项工作。我可以获得更好的代码吗? 有人认为,分担任务不是正确的事情。但是我想知道是否必须平均分配任务,那么解决方案是什么。

0 个答案:

没有答案