一般竞争条件

时间:2015-03-07 21:06:11

标签: c multithreading mutex

我是C的新手,想了解比赛情况。我在互联网上找到了它,并要求找到竞争条件,并找到解决方案。

我的分析是,create-thread()方法中的竞争条件具有竞争条件,特别是在if-else语句中。因此,当访问该方法时,可以在check-and-act期间创建或删除另一个线程,并且thread_amt将关闭。

为了不具备竞争条件,请使用互斥锁,信号量等锁定if-else

如果我错了,任何人都可以纠正我,并且可能告诉我如何实现互斥?

#define MAXT 255
int threads_amt = 0;
int create-thread() // create a new thread
{
    int tid;
    if (threads_amt == MAXT) return -1;
    else
    {
        threads_amt++;
        return tid;
    }
}
void release-thread()
{
    /* release thread resources */
    --threads_amt;
}

2 个答案:

答案 0 :(得分:1)

是的,在这种情况下发生的竞争条件是因为您无法保证threads_amt的检查和操作将在没有中断/执行另一个线程的情况下发生。

我头顶的三个解决方案:

1)使用二进制信号量(或互斥锁)强制互斥这部分代码以保护if-else部分。

2)使用初始值为MAXT的信号量,然后在调用create_thread时(注意,你不能在函数名中使用连字符!),使用" wait()" (取决于信号量的类型,它可以有不同的名称(例如sem_wait()))。之后,创建线程。调用release_thread()时,只需使用" signal()" (sem_post(),使用semaphore.h时)。

3)这更像是一个硬件"解决方案:您可以假设您获得了执行整个if-else部分的原子函数,因此避免了任何竞争条件问题。

在这些解决方案中,最简单的"一个(基于你已经拥有的代码)是第一个。

让我们使用semaphore.h的信号量:

#define MAXT 255

// Global semaphore 
sem_t s;
int threads_amt = 0;

int main () {
    ...
    sem_init (&s, 0, 1); // init semaphore (initial value = 1)
    ...
}


int create_thread() // create a new thread
{
    int tid;
    sem_wait(&s);
    if (threads_amt == MAXT) {
        sem_post(&s); // the semaphore is now available
        return -1;
    }
    else
    {
        threads_amt++;
        sem_post(&s); // the semaphore is now available
        return tid;
    }
}
void release_thread()
{
    /* release thread resources */
    sem_wait(&s);
    --threads_amt;
    sem_post(&s);
}

这应该可以正常工作。

我希望它清楚。如果不是,我建议您研究信号量如何工作(使用网络,或购买一些操作系统书)。另外,你提到你是C的新手:恕我直言,你应该从比这更简单的事情开始:信号量并不是你想要在“你好世界”之后学到的下一件事。 ; - )

答案 1 :(得分:0)

竞争条件不在if()陈述中。

可以访问可能在多个线程中同时更改和访问的变量threads_amt

基本上,修改变量的任何线程都必须具有独占访问权限以避免竞争条件。这意味着必须同步修改变量或读取其值的所有代码(例如,首先获取互斥锁,然后释放)。读者不一定需要独占访问权限(例如,同时读取的两个线程不会相互影响)但是编写者会这样做(因此在尝试在另一个线程中更改它时避免读取值) - 这样的考虑因素可能有机会使用除互斥锁之外的同步方法 - 例如,信号量。

要使用互斥锁,必须先创建它(例如在项目启动期间)。然后在需要时抓住它,并记得在完成后释放它。每个函数都应该最小化它持有互斥锁的时间,因为其他尝试获取互斥锁的线程将被迫等待。

诀窍是无论何时发生互斥都无条件地抓取和释放互斥锁(即避免抓住互斥锁的功能,能够返回而不释放互斥锁)。这取决于你如何构建每个函数。

实现的实际代码取决于您使用的线程库(因此您需要阅读文档),但概念是相同的。所有线程库都具有创建,抓取(或输入)和释放互斥锁,信号量等功能。