【问题标题】:Peterson's Algorithm with Threads and Linked List (C language)带线程和链表的 Peterson 算法(C 语言)
【发布时间】:2026-02-03 09:15:02
【问题描述】:

我有以下情况:

首先,我创建了一个 int 链表(已经可以工作了,这个没问题),我需要执行以下任务:

使用 2 个线程,一个线程将删除我列表的第一个元素,然后同一线程必须在列表末尾添加一个新元素(列表遵循 FIFO 结构)。

第二个线程会做同样的事情:删除第一个元素并在列表末尾添加另一个元素。

我需要多次执行这个操作,这显然是通过使用循环来完成的。

当我创建一个线程时,我使用以下函数:

for(i=0, i<NUM_THREADS; i++)
    pthread_create (&thread[i], NULL, threadBody, (void *) i);

其中 NUM_THREADS 是一个变量,包含我将使用的线程数(在本例中为 2),线程声明为:

pthread_t thread [NUM_THREADS] ;

所以,我的问题是:

我是否需要在我的 threadBody 函数上执行我之前所说的操作(在我的列表中添加和删除元素),否则这个函数将为空?

如果我的 threadBody 函数不打算执行此操作,我如何使用我创建的线程来执行这些操作?是通过使用 pthread_join 函数完成的吗?

另一点是我需要使用彼得森算法来保证互斥。我该怎么做?

【问题讨论】:

  • 你的问题太宽泛了,很难得到一个简洁的答案。但对于初学者:是的,您应该在 threadBody 中编写添加/删除代码。您可能应该为生产者和消费者使用不同的 threadBody 代码(或者您可以使用相同的 threadBody 并在创建期间向其传递一个参数,告诉它充当消费者或生产者)。对于互斥,我建议您参考 pthread_mutex_lock 和 pthread_mutex_unlock 手册页。
  • 彼得森算法是 80 年代初开发的一种无锁多任务处理形式。它在当时存在的处理器上运行良好。现代处理器具有许多功能,即使不是不可能,也很难正确实现无锁多任务处理。例如,请参阅this article
  • 你有两个线程,所以使用彼得森算法不是问题。只要有threadBodyAddthreadBodyRemove。在你的回合/我的回合变量上同步它们,你就完成了。

标签: c multithreading algorithm mutual-exclusion


【解决方案1】:

我可以看到您对链表的操作很简单。在这种情况下,使用无锁编程可能会更好。要阅读,请查看此link。如果您使用 GCC,请查看 __sync_bool_compare_and_swap 操作 (link)。最后,无锁链表的编程问题得到了广泛的研究。下一个链接可能会为您提供有关它的提示link。祝你好运!

【讨论】:

    【解决方案2】:

    谢谢大家。

    我的最终实现(和工作)是:

    void *threadBody (void *id){
        long threadId = (long) id;
        int k=0;
        while(k<N){
            if(threadId == 0){
                 flag[0] = 1;
                 turn = 1;
                 while(flag[1]==1 && turn==1);
             }
             else{
                 flag[1] = 1;
                 turn = 0;
                 while(flag[0]==1 && turn==0);
             }
             critSection(id);
             if(threadId==0) 
                flag[0] = 0;
             else if(threadId==1) 
                flag[1] = 0;
             k++;
        }
        pthread_exit (NULL) ;   
    }
    

    critSection 将是执行添加/删除操作的函数。

    【讨论】: