帮助使用信号量和线程
我正在使用 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);
}
您还可以下载所有代码或查看日志文件...
下载 main.c 文件。 .cpp 查看日志文件: funkohland.com/pthreads/log.txt
I am using the pthread library to simulate a threaded buffer. I am also using semaphores as a solution to accessing critical section variables one at a time.
The main problem is that the producer is filling the entire buffer and the consumer is then emptying the entire buffer. Is this code correct? I was assuming that the production and consumption would occur before the buffer was full or empty.
Here is my code and any comments would help a lot, and yes this is for a class.
Thank you in advance
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);
}
You can also download all the code or see the log file...
download main.cpp
view the log file at funkohland.com/pthreads/log.txt
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是互斥锁的一个众所周知的问题。互斥量是一项昂贵的操作,需要大量的周期。当您解锁互斥体时,另一个线程有很小的机会退出其锁并获得锁。基本上,您需要在互斥锁上花费更少的时间,以便为其他线程提供运行的机会。基本上,您需要选择实际需要互斥锁的代码部分,然后快速锁定互斥锁,执行您需要对该变量执行的任何操作(仅此而已),然后解锁它。
This is a well known problem with Mutexes. A Mutex is an expensive operation that requires lots of cycles. When you unlock the mutex the other thread has a TINY opportunity in which to exit its lock and gain a lock. Basially you need to spend less time in the mutex to give the other thread an opportunity to run. Basically you need to choose the portion of code that ACTUALLY required the mutex and then lock the mutex quickly do whatever you need to do with that variable (and nothing more) and then unlock it.
对于初学者,您应该确保对共享变量“c”和“size”的访问在关键部分内进行。这是锁定和解锁调用之间的情况。目前,您可以自由访问“c”,有时还可以访问“size”,而无需正确锁定。
For starters, you should ensure that access to shared variables 'c' and 'size' are carried inside a critical section. Thats between a lock and unlock calls. Currently you are freely accessing 'c' and sometimes 'size' without proper locking.
虽然 Goz 的答案是原因,但可能的解决方案是使用
usleep(1)
或sched_yield()
/Sleep(0 )
(取决于操作系统)。另外,由于您的生产者使用 rand(),所以它没有什么区别,但如果它使用耗时的 I/O 或高级算法来插入新对象,则正确的方法是执行实际生产未互斥的操作,将其转换为本地缓冲区,然后仅互斥体将新创建的对象插入队列。
While Goz's answer is the reason, the possible solution is to yield to scheduler outside the mutex, either using
usleep(1)
orsched_yield()
/Sleep(0)
(depending on OS).Also, since your producer uses rand(), it makes little difference but if it was using time-consuming I/O or advanced algorithms for making the new objects to be inserted, the right approach is to perform the actual production unmutexed, into a local buffer, then only mutex inserting the newly created object into the queue.