填充列表大小,pthreads弹出列表

时间:2012-06-16 19:21:27

标签: c++ c pthreads linked-list singly-linked-list

我有一个单链表,每个元素包含1个值。

struct listElement
{
    char guid[20];
    struct listElement *next;
    struct listElement *last;
    int numElements;
};

代码在池中启动10个pthread,它们都是pthread_cond_wait(),以便将元素添加到列表中。

我的main()正在读取文件中的字符串,一次一行,并通过调用listPush(val)填充链接列表

listPush(val)获取锁定,创建新元素,添加到列表末尾(或创建头部,如果为空)解锁然后调用pthread_cond_signal()让10个线程中的一个知道现在有一个元素有工作要做。

在numElements>的情况下numThreads我调用pthread_cond_broadcast(),因为每个线程都应该有足够的工作来弹出。

每个线程listPop(rVal)关闭一个值(锁定,删除,修复指针,解锁)并对其进行处理,然后返回pthread_cond_wait()状态。

我的文件大约有2亿行。 (1.2GB)我不希望我的链表变得这么大,所以我试图“限制”链表的大小。

listPush()内,在锁定互斥锁之前,我有

if(head && head->numElements >= maxNumElements)
{
    while(head && head->numElements >= maxNumElements)
    {
        sleep(1);
    }
}

这个想法是,如果我“填满”我的列表,我会等待线程处理它的一大块,然后再添加更多。我已经达到了应用程序开始“脉动”的程度;基本上我可以看到它等待1秒。我希望这种情况永远不会发生或很少发生。

除了使用sleep()之外,还有更好的方法来限制列表的大小吗?

2 个答案:

答案 0 :(得分:0)

是的,而不是使用睡眠,您可以等待信号量(类似于互斥量,但以其他方式),并在将新元素添加到列表时唤醒。您可能能够找到事件库或使用pthreads自己完成。

答案 1 :(得分:0)

这听起来像是经典producer-consumer problem。如果列表太大,解决方案是让listPush()等待条件变量。然后,一旦使用了列表元素,其中一个消费者线程就会发出这个条件变量的信号。

完全不同的方法是使用pipe()来处理通信和同步。这样就不需要链表和互斥锁。