我正在完成一项家庭作业,我必须在C中编写一个多线程的linux程序来解决操作系统类的生产者 - 消费者问题。在我的代码中,我有一个while
循环,它位于由单个线程运行的函数内。在该函数中,我增加了一个受mutex
保护的变量。
问题在于,while
循环有时会比我期望的更多时间。例如,当我期望循环执行16
次时,它有时会执行17
次。我无法弄清楚这个bug的原因,但它似乎与线程有关。我已将代码最小化,问题仍然可以重现。
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
int numItems = 16;
pthread_t threadID;
pthread_t threadID2;
pthread_mutex_t mutex;
pthread_attr_t attr;
void *produce(void *param);
int numItemsProduced = 0;
int main(int argc, char *argv[])
{
pthread_attr_init(&attr);
// Initialize mutex.
if (pthread_mutex_init(&mutex, NULL) != 0)
{
printf("%s\n", "An error occured while initializing mutex!");
}
pthread_create(&threadID, &attr, produce, NULL);
pthread_create(&threadID2, &attr, produce, NULL);
pthread_join(threadID, NULL);
pthread_join(threadID2, NULL);
printf("Finished.\n");
}
void *produce(void *param)
{
printf("In thread.\n");
while (numItemsProduced < numItems)
{
pthread_mutex_lock(&mutex);
printf("Current while loop is at int %d\n", numItemsProduced);
numItemsProduced++;
pthread_mutex_unlock(&mutex);
}
pthread_exit(0);
}
为什么while
循环有时会执行额外的时间?我相信我正在使用mutex
。
答案 0 :(得分:2)
问题是由线程在进入while循环后等待互斥锁引起的。您需要在输入关键代码后再次检查条件:
method1
答案 1 :(得分:0)
您的问题在以下一行
while (numItemsProduced < numItems)
此行中没有线程安全,因为您尚未锁定互斥锁。 您应该锁定互斥锁以检查条件并更新值。
可以改写为:
while (1)
{
pthread_mutex_lock(&mutex);
if (numItemsProduced >= numItems)
{
pthread_mutex_unlock(&mutex);
break;
}
printf("Current while loop is at int %d\n", numItemsProduced);
numItemsProduced++;
pthread_mutex_unlock(&mutex);
}
或者如果使用c ++:
struct LockGuard
{
LockGuard(pthread_mutex_t* mutex) : _pmutex(mutex)
{
pthread_mutex_lock(_pmutex);
};
~LockGuard()
{
pthread_mutex_unlock(_pmutex);
}
private:
LockGuard(const LockGuard&); // or use c++0x ` = delete`
pthread_mutex_t* _pmutex;
};
while (true)
{
LockGuard(&mutex);
if (numItemsProduced >= numItems)
{
break;
}
printf("Current while loop is at int %d\n", numItemsProduced);
numItemsProduced++;
}
答案 2 :(得分:-1)
void *produce(void *param)
{
printf("In thread.\n");
while (1)
{
pthread_mutex_lock(&mutex);
if(numItemsProduced >= numItems){
pthread_mutex_unlock(&mutex);
break;
}
printf("Current while loop is at int %d\n", numItemsProduced);
numItemsProduced++;
pthread_mutex_unlock(&mutex);
}
pthread_exit(0);
}