什么是线程

Mas*_*der 2 c++ multithreading objective-c

我一直在网上看线程是什么,我不觉得我理解它.有人可以对此有所了解吗?在与C++相关的编程语言方面,objective-C会很好.

在objective-c中,我遇到了

@property(nonatomic, strong) NSString *name;
Run Code Online (Sandbox Code Playgroud)

非原子的解释是它意味着不要担心多个线程同时试图访问该对象,而objective-c不必合成线程安全代码.那么这究竟意味着什么呢?

nne*_*neo 6

一个进程可以包含多个执行线程,逻辑上可以认为它们是彼此同时运行的.每个线程独立运行,但共享相同的内存和进程状态.单个线程可以"做一件事":执行计算,与网络交互,更新UI,解码视频,等等.但是,一个线程不能做所有这些在一次无显著从程序员的额外工作量.在进程中拥有多个线程使程序员能够轻松地使应用程序同时执行多个操作(多任务处理).

但是,使用多线程确实会带来一些新的挑战.例如,如果您有两个访问同一变量的线程,则最终可能会遇到并发危险,其中在另一个线程访问该变量之前,该变量可能无法由一个线程完全更新,从而导致程序失败.Objective-C默认生成线程安全的代码,以避免这种情况.nonatomic告诉编译器你永远不会同时从多个线程访问它,因此编译器可以跳过线程安全代码并生成更快的代码.无论如何,如果您要提供自己的同步(例如,保持一组属性同步,Objective-C本身无法帮助您),这将非常有用.

如果你违反了核心nonatomic假设并同时nonatomic从多个线程访问变量,那么一切都会破裂.

  • 原子属性并不意味着线程安全的代码!这是一个巨大的误解,它只是意味着你的财产将以原子方式获得和设置!在大多数情况下,适当的同步是在不同的级别上完成的,并且getter/setter对它没有影响. (4认同)

Ton*_*roy 5

对非原子的解释是,它意味着不必担心多个线程同时尝试访问对象,并且 Objective-C 不必合成线程安全代码。那么这究竟意味着什么呢?

想象一下,你被要求在一张纸上写下你的名字。您会收到一份有人认为可以正常工作的指令列表:

  • 你发现一行当前是空的,
  • 将笔移到上面,
  • 写你的名字。

都好。

现在想象一下,你得到了一张新纸,但你和其他人都被要求在同一张纸上写下你们的名字,并且你得到了旧的指示,也许:

1)你们俩看着纸,决定写在第一行。2)你放下笔(也许你们都可以很舒服地做——一只左手/一只右手)。3) 你开始写一个 I,但另一个人写一个 J,结果看起来像一个 U。 4) 从这里开始变得更糟......

但同样,您可能会更加注意,并在他们开始寻找空行之前写完您的名字,反之亦然。

线程很像这样......在上面的例子中,每个线程/人都在跟踪他们在任务上的进展情况,非常严格地遵循他们的指示。请注意,如果您只完成第 1 步,那么其他人也执行第 1 步,那么无论其余步骤的顺序或并发性如何,你们都已经设置好重写彼此的名字。

在所有这一切中,您甚至不必在同一时刻及时做事,只是您的任务跟踪是独立的 - 您是独立的人,拥有自己的记忆,知道自己在任务中的位置。与线程相同 - 它们是跟踪独立执行操作的方法,并且它们是否实际上同时在程序中执行操作是可选的(这对于多核 CPU 和多 CPU 系统是可能的)。

“原子”的意思是不可分割的(想一想:你不可能把金原子切成两半而仍然有金)。类似地,如果你说原子地写下你的名字,这意味着任何观察者都可以保证目睹前一瞬间 - 当没有名字时 - 或后一瞬间 - 当你的名字被完全写下时 - 但他们永远不会看到你的一半姓名。字符串变量的原子更新就是这样。

原子字符串更新不能解决上述问题......您可能仍然会在查找“空行”时发生冲突(在计算上下文中 - 比如说在容器中查找下一个空位置)。如果查找空行的过程是原子的,并且甚至在您自己编写任何内容之前该行就以某种方式标记为“已使用”,那么这意味着您永远不会得到与其他人相同的行。在那个阶段,多个人写下自己的名字不会在同一行上发生冲突,但只有当行查找和名字书写都是原子的时,人们看论文才能知道他们看到的是完全书写的不冲突的名字。

做出此类保证非常有用,但成本高昂。这意味着线程必须在它们之间进行通信和协调,同意“谁”将首先执行,而其他线程则在必要时等待。