我一直在网上查看线程是什么,但我不觉得我理解它。有人可以对此有所了解吗?就与 C++ 相关的编程语言而言,objective-C 会很好。
在objective-c中,我遇到了
@property(nonatomic, strong) NSString *name;
对非原子的解释是,它意味着不必担心多个线程同时尝试访问对象,并且objective-c 不必合成线程安全代码。那么这到底意味着什么。
我一直在网上查看线程是什么,但我不觉得我理解它。有人可以对此有所了解吗?就与 C++ 相关的编程语言而言,objective-C 会很好。
在objective-c中,我遇到了
@property(nonatomic, strong) NSString *name;
对非原子的解释是,它意味着不必担心多个线程同时尝试访问对象,并且objective-c 不必合成线程安全代码。那么这到底意味着什么。
一个进程可以由多个执行线程组成,从逻辑上讲,这些线程可以被认为是同时运行的。每个线程独立运行,但共享相同的内存和进程状态。单个线程可以“做一件事”:执行计算、与网络交互、更新 UI、解码视频等。但是,如果没有程序员的大量额外工作,单个线程无法同时完成所有这些工作. 在一个进程中拥有多个线程使程序员能够轻松地使应用程序同时执行多项操作(多任务处理)。
不过,使用多线程确实会带来一些新的挑战。例如,如果您有两个线程访问同一个变量,您最终可能会遇到并发风险,其中一个线程可能在另一个线程访问它之前没有完全更新该变量,从而导致程序失败。Objective-C 默认会生成线程安全的代码,以避免这种情况。nonatomic
告诉编译器您永远不会同时从多个线程访问它,因此编译器可以跳过线程安全代码并生成更快的代码。无论如何,如果您要提供自己的同步(例如,保持一组属性同步,Objective-C 本身无法帮助您),这将很有用。
如果您违反核心nonatomic
假设并同时nonatomic
从多个线程访问一个变量,那么所有的地狱都会崩溃。
explanation for nonatomic was it means to not be worried about multiple threads trying to access the object at the same time, and objective-c does not have to synthesize thread safe code. So what does that exactly mean as well.
Imagine you are asked to write your name on a piece of paper. You're given a list of instructions someone thought would work just fine:
All good.
Now imagine you're given a new piece of paper, but both you and someone else are asked to write your names on the same piece of paper, and you're given the old instructions, perhaps:
1) You both look at the paper and determine to write on the first line. 2) You put your pens down (maybe you can both do it comfortably enough - one left / one right handed). 3) You start to write an I but the other person is writing a J and it comes out looking like a U. 4) gets worse from here....
But equally, it might be that you're paying more attention, and finish writing your name before they start looking for an empty line, or vice versa.
Threading is a lot like this... in the above example, each thread/person is keeping track of how they're progressing at the task, following their instructions very literally. Notice that if you complete only step 1, then the other person does step 1, you've already set yourselves up to write over each others' name regardless of the ordering or concurrency of the remaining steps.
In all this, you don't even have to be doing things at the same instant in time, it's just that the tracking of your tasks is independent - you're independent people with your own memory of where you are in your task. Same with threads - they're ways of tracking what to do independently, and it's optional whether they actually do things in your program at the same instant (which is possible with multi-core CPUs and multi-CPU systems).
"atomic" is used in the sense of indivisible (think: you can't cut an atom of gold in half and still have gold). Similarly, if you say write your name atomically, it means any observer is guaranteed to either witness the instant before - when no name is there - or the instant after - when your name is completely written - but they'll never see just half your name. An atomic update on a string variable is like that.
Atomic string updates don't solve the problem above... you might still clash in finding "an empty line" (in a computing context - say finding the next empty position in a container). If that process of finding an empty line is atomic, and the line is somehow marked "used" even before you've written anything on it yourself, then it means you'll never get the same line as someone else. At that stage, multiple people writing their names won't clash on the same line, but only when both the line finding and the name writing are atomic can people looking at the paper know that they're seeing completely written non-clashing names.
Making these kind of guarantees is very useful but expensive. It means that threads must communicate and coordinate amongst themselves, agreeing "who" will go first with others waiting as necessary.