帮助使用信号量和线程

时间:2010-07-06 06:50:51

标签: c++ pthreads buffer

我正在使用pthread库来模拟线程缓冲区。我也使用信号量作为一次访问一个关键部分变量的解决方案。

主要问题是生产者正在填充整个缓冲区,然后消费者正在清空整个缓冲区。这段代码是否正确?我假设生产和消费将在缓冲区满或空之前发生。

这是我的代码,任何评论都会有很多帮助,是的,这是一个类。

提前谢谢

void *Producer(void *threadid) 
{
   long tid;
   tid = (long)threadid;

   while (c < Cycles)  //While stuff to buffer
   {                        
        pthread_mutex_lock(&lock);           
        while(size == BUFFER_SIZE)  
        {
           pthread_cond_wait(&cond, &lock);    
        }
     buffer [full] = rand();
     data << size+1 << ". Produce: " << buffer[full] << endl;
     printBuffer();
     full = (full + 1) % BUFFER_SIZE;
     size++;
     pthread_cond_signal(&cond1);
     pthread_mutex_unlock(&lock);
     c++;
   }
   pthread_exit(NULL);
}

您也可以下载所有代码或查看日志文件......

download main.cpp 在funkohland.com/pthreads/log.txt查看日志文件

3 个答案:

答案 0 :(得分:1)

这是互斥锁的一个众所周知的问题。互斥是一种昂贵的操作,需要大量的周期。解锁互斥锁时,另一个线程有一个TINY机会,可以在其中退出锁定并获得锁定。基本上你需要花费更少的时间在互斥锁上,让其他线程有机会运行。基本上你需要选择实际上需要互斥锁的代码部分然后快速锁定互斥锁做任何你需要处理的变量(而不是更多),然后解锁它。

答案 1 :(得分:0)

对于初学者,您应该确保在关键部分内访问共享变量'c'和'size'。这是锁和解锁电话之间的关系。目前,您可以在没有正确锁定的情况下自由访问“c”,有时“大小”。

答案 2 :(得分:0)

虽然Goz的答案是原因,但可能的解决方案是使用usleep(1)sched_yield() / Sleep(0)(取决于操作系统)向互斥锁之外的调度程序投入使用。

此外,由于您的生产者使用rand(),因此它没有什么区别,但是如果它使用耗时的I / O或高级算法来插入新对象,那么正确的方法是执行实际生产unmutexed ,进入本地缓冲区,然后只将互斥锁插入队列中。