C 在使用线程时,我会遇到哪些问题?

C 在使用线程时,我会遇到哪些问题?,c,multithreading,winapi,C,Multithreading,Winapi,我了解了使用线程时可能遇到的以下问题: 当您将一个值写入内存中的变量时,该值不一定写入内存位置,该值可以写入缓存,因此如果另一个线程正在读取该变量,它将不会读取另一个线程刚刚写入的值 另外,当您从内存中的变量读取时,值不一定从内存位置读取,值可以从缓存中读取,因此如果另一个线程向该变量写入了值,并且您的线程正在尝试读取该值,那么它将不会读取另一个线程刚刚写入的值 您需要注意的是,某些任务需要是原子的,因此,例如,如果两个线程正在对一个变量进行计算,则不能允许这两个线程同时进行计算,一个线程必须等

我了解了使用线程时可能遇到的以下问题:

当您将一个值写入内存中的变量时,该值不一定写入内存位置,该值可以写入缓存,因此如果另一个线程正在读取该变量,它将不会读取另一个线程刚刚写入的值

另外,当您从内存中的变量读取时,值不一定从内存位置读取,值可以从缓存中读取,因此如果另一个线程向该变量写入了值,并且您的线程正在尝试读取该值,那么它将不会读取另一个线程刚刚写入的值

您需要注意的是,某些任务需要是原子的,因此,例如,如果两个线程正在对一个变量进行计算,则不能允许这两个线程同时进行计算,一个线程必须等待另一个线程完成其计算

编译器和/或CPU可能会无序执行程序指令

如果每个线程都在等待另一个线程发出信号,然后再继续,则可能会出现死锁

在使用线程时,我还可以面对其他问题吗

当您将值写入内存中的变量时,该值不一定会写入内存位置,而可以将该值写入缓存

你在错误的抽象层次上思考它。您所说的是正确的,但是您所使用的编程语言工具链的开发人员主要对此感兴趣。从应用程序开发人员的角度来看,最好说一个线程写入内存的值不会立即对其他线程可见

编译器和/或CPU可能会无序执行程序指令

更好的说法是,当一个线程按顺序将多个值写入内存时,其他线程不一定会看到新值以相同的顺序出现

在任何单个线程中,编译器和CPU都必须确保一切都按程序顺序发生

…某些任务需要是原子的,因此,例如,如果两个线程正在对一个变量进行计算,则不能允许这两个线程同时进行计算

同样正确,但这还不够有用的信息。您需要知道两个不同的线程可以或不能同时进行计算的时间和原因

关键概念是不变量。不变量是指总是假定为真的任何条件。例如,如果您正在实现一个链表结构,一个不变量是每一个下一个指针要么指向列表的一个成员,要么指向NULL。如果要实现一个由链接节点组成的环,那么一个不变量表示,如果您沿着下一个指针链走得足够远,它将始终带您回到开始的位置

通常情况下,如果不临时破坏不变量,就无法执行某些操作。例如,如果不将某个数据结构暂时置于无效状态,您可能无法将某些内容插入到该数据结构中


你说过,有些任务需要“原子化”。更确切地说,有些任务需要互斥互斥互斥,以防止一个线程看到由于其他线程的操作而导致的处于临时中断状态的不变量。

google about RaceConditions函数需要是可重入的。C标准库是相当安全的,strtok是一个显著的例外。我发现我可以使用一个关键部分来强制WinAPI中的互斥。但我如何做到以下几点:1确保当一个线程将值写入变量时,该值直接写入内存,即其他线程可以看到它;2我如何确保我指定的一组指令将按照我写入它们的相同顺序执行?@Christopher,答案取决于您使用的系统的内存模型。如果您使用Java,我可以确切地告诉您在哪里可以找到Java内存模型的正式描述。我不太了解C和C++,但是大多数系统至少能保证这么多:如果线程A在解锁一些锁之前写入内存,然后线程B锁定同一个锁,线程B将能够看到A线程写了什么。RE 2,至少不能,不必求助于编译器/版本特有的技巧,您的操作系统/版本和/或处理器。在任何单个线程中,这都无关紧要。任何单个线程的执行都将始终与您编写的代码具有相同的效果。在线程之间,必须使用互斥锁或其他同步方法,以确保线程只能看到处于有意义的一致状态的共享数据结构。