在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在转移到消费者之前完成所有生产者工作。但是,消费者接连进行这项工作。我可以获得更好的代码吗? 有人认为,分担任务不是正确的事情。但是我想知道是否必须平均分配任务,那么解决方案是什么。