我有两个结构如下:
typedef struct _product
{
unsigned int product_id;
time_t my_time_stamp;
unsigned int lifespan;
} product;
typedef struct _queue
{
product * elem;
struct _queue * next;
} queue;
我有一个全局变量头。
queue *head;
在主要的我malloc队列的头部。
head = (queue *)malloc(sizeof(queue));
并在另一个函数中调用它
if(head->elem == NULL) { head = newPointer; }
当我把头部摩托起来时,一切都很好。然后当它跳转到函数时,它会重置为0x0。
这是错误的方法吗?如果是这样,应该怎么做?
void producer_func(void *tid)
{
while(number_of_products_created < number_of_products_max) //check for completeness of task
{
my_str("in producer with id ");
my_int((long)tid);
br();
pthread_mutex_lock(&the_mutex);
my_str("locked by ");
my_int((long)tid);
br();
while(space_in_queue >= size_of_queue)
pthread_cond_wait(¬Full, &the_mutex); //check to see if there is room in the queue
product *tempProduct = malloc(sizeof(product));
//////////////enter critical region/////////////
tempProduct->product_id = product_id_count++;
//////////////exit critical region/////////////
//time
struct timeval tim;
gettimeofday(&tim, NULL);
tempProduct->my_time_stamp = tim.tv_sec;
//endtime
tempProduct->lifespan = rand();
//new item for queue
queue *newPointer = malloc(sizeof(queue));
newPointer->elem = tempProduct;
newPointer->next = NULL;
//critical region//
if(head == NULL)
{
head = newPointer;
}
else
{
//traverse list
queue *tempPointer;
tempPointer = head;
while(tempPointer->next != NULL)
{
tempPointer = tempPointer->next;
}
tempPointer->next = newPointer;
}
space_in_queue++;
number_of_products_created++;
//end critical region//
my_str("unlocked by ");
my_int((long)tid);
br();
usleep(10000);
my_str("num products created is ");
my_int(number_of_products_created);
br();
usleep(10000);
pthread_cond_broadcast(¬Empty);
pthread_mutex_unlock(&the_mutex);
usleep(100000); //let others have a chance
}
}
答案 0 :(得分:4)
锁定互斥锁并释放互斥锁之间的代码很多。您应该尽量减少锁定所做的工作量。除了将项目添加到列表而没有锁定之外,您应该完成所有工作。只有当一切准备就绪时,您才能获取互斥锁并继续添加项目并释放互斥锁。将列表末尾的项添加为O(1)而不是O(N)操作也是一个好主意 - 保持指向结构尾部的指针。如果在互斥锁保持锁定的情况下一次睡眠10毫秒,那么你真的不会从系统中获得良好的性能(并发性)。
另一个批评是,您的产品结构将在许多64位平台上占用24个字节,而不仅仅是16.如果time_t
是8字节数量,8字节数量在8字节边界上对齐,你在每个unsigned int
值之后浪费了4个字节。
然而,这只是一般性的批评 - 而不是直接导致你的问题。
您似乎没有初始化使用queue
分配的malloc()
。由于malloc()
返回未初始化的数据,因此它可以包含任何内容。在执行任何其他操作之前,必须将其转换为正确形成的队列项 - 使用初始化指针等。
答案 1 :(得分:0)
我认为head
是一个全局变量。不知道为什么你的函数没有在那里找到一个好的值,但你可以避免所有的问题,只是没有它的指针变量:
queue head = {0};
然后您的列表将始终定义良好,您甚至不必检查它。您的列表的空白与否的语义会改变。
Jonathan说你的关键部分有很多代码是对的。特别是,在这样的部分睡觉真是个坏主意。