简体   繁体   English

找不到僵局

[英]Can't find the deadlock

I got this question in a job interview and for the life of me I couldn't find the answer (and they don't tell you the answer at the end since it's a written test): 我在求职面试中遇到了这个问题,在我的生命中,我找不到答案(由于这是笔试,他们最后没有告诉你答案):

int thread2_finished = 0;

void t1() {
    printf("t1 is running\n");
    while (!thread2_finished) { usleep(50); }
    printf("t2 is doing stuff\n");    
}


void t2() {
    printf("t2 is running\n");
    sleep(5);
    printf("t2 woke up\n");    
    thread2_finished = 1;
    printf("t2 finished\n");
}

What we know is that most of the times it works - but sometimes thread1 never exists (doesn't print the last message) while thread2 does print all his messages - How is that possible? 我们所知道的是,大多数情况下它都能正常工作-但有时thread1永远不存在(不显示最后一条消息),而thread2 确实打印了他的所有消息-怎么可能?

I'm guessing i'm missing something basic here but the only thing I could think about it that the problem is with the cache - like T1 loads the value (0) and cache it, then immediately T2 changes the value to 1, but for some odd reason T1 will keep using the old cached value but that seems weird to me. 我想我这里缺少基本的东西,但是我唯一能想到的是缓存问题-像T1加载值(0)并缓存它,然后T2立即将值更改为1,但是由于某些奇怪的原因,T1将继续使用旧的缓存值,但这对我来说很奇怪。

像这样写的代码似乎是正确的(并且是一种逻辑方式),但是如果您使用真实环境,它将无法正常工作,此修复将是volatile关键字,但是原因有点复杂,还因为此关键字的行为更改每种语言/编译器,此处提供正确答案

You have no guarantee that t1 has started when t2 runs. 您无法保证t2运行时t1已经开始。 sleep is not a valid substitute for proper thread synchronization. sleep不是适当的线程同步的有效替代。

One could also argue that thread2_finished should be volatile. 有人可能会说thread2_finished应该是易失的。 In reality that shouldn't really matter since the compiler doesn't know what usleep does and therefore can't assume that usleep won't change global variables. 实际上,这并不重要,因为编译器不知道usleep做什么,因此不能假定usleep不会更改全局变量。 On the other hand, on many architectures you need to have better synchronization than just updating a global variable. 另一方面,在许多体系结构上,您需要的同步不仅仅是更新全局变量。 On some the other thread (if running on a different cpu) might not see the updated value of the global variable for a long time, on others (if not cache coherent) it might never see it. 在某些其他线程(如果在不同的cpu上运行)上可能长时间看不到全局变量的更新值,而在其他线程(如果没有缓存一致)上,则可能永远看不到它。 The locking primitives in the operating system should provide enough logic to make sure that side effects from one thread are seen by other threads. 操作系统中的锁定原语应提供足够的逻辑,以确保一个线程的副作用被其他线程看到。

In short - even though this could work in most cases, never do this. 简而言之-即使这在大多数情况下都可行,但绝对不要这样做。 Use proper locking, condition variables and semaphores. 使用适当的锁定,条件变量和信号量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM