当前位置:编程学习 > C#/ASP.NET >>

多核CPU怎么保证线程同步?求解!

在单核CPU中,由于在某个时刻,只有一个线程执行,因此对于一些原子操作,永远不会在两个线程拥有
那多核CPU中是怎么保证某些原子操作,比如两个线程分别在两个CPU中运行,并且在同一时刻对同一内存区域进行操作,那么多核CPU是怎么保证线程同步的呢? 原子操作 线程同步 多核CPU --------------------编程问答-------------------- 什么“原子操作”?就算是单核,你有多少可以代码肯定是“原子操作”的呢?

不论是单核还是40核,编程都是一样的。

满大街都是代码,可是概念不对的话你是视而不见的(因为你不相信)。 --------------------编程问答-------------------- 既然你认为问题仅仅存在于“多核”,那么请先说明你在“多核”时是如何进行线程同步的吧。不然你提的问题,反倒好像是你把问题变成了考别人是否知道你的答案似地。 --------------------编程问答-------------------- 请先说明你在“多核”时是如何进行线程同步的  -->  请先说明你在“单核”时是如何进行线程同步的 --------------------编程问答-------------------- 支持SMP方式工作的CPU有基于硬件实现的锁和仲裁机制。 --------------------编程问答-------------------- 当然了,也正因为如此,简单共享存储的多处理机系统的效率是很低的,一般我们认为超过32个CPU,这种简单的架构就不适合了。 --------------------编程问答--------------------
引用 4 楼 caozhy 的回复:
支持SMP方式工作的CPU有基于硬件实现的锁和仲裁机制。


非常感谢您的回答,我的意思是,比如两个CPU(32位),此时各运行一个线程
说具体点,线程1正执行写入一个Int32操作,线程2执行读取一个Int32操作,并且他们操作的是同一内存区域
在单线程中,同一时刻,单条指令永远只会在一个线程中执行,不可能同时在两个线程中执行

那在双核CPU中,各有一个线程,并且同时执行这下面两条指令时,是怎么保证线程同步的呢?
线程1:mov dword ptr [ebp-40h],12345678h //写入
线程2:mov  ecx,dword ptr [ebp-40h] //读取

我老是听到同样的说明:“这是由于硬件实现的锁和仲裁机制”这句话怎么理解呢?

是不是硬件中有一个缓冲区,当即使两条指今同时在CPU执行,但指令到达硬件(内存)时,还是会维护一个运行时序,还是有一个先后顺序的,当一个指令执行时,会存在一个Memory Barrier的机制,来保护执行的内存,另一条指令在硬件中会有一个类似阻塞效果的空转操作呢?

不好意思,由于我是一个菜鸟,可能表达的不清楚,期待你的回答,谢谢! --------------------编程问答--------------------
引用 3 楼 sp1234 的回复:
请先说明你在“多核”时是如何进行线程同步的  -->  请先说明你在“单核”时是如何进行线程同步的

非常感谢您的回答,我的意思是,比如两个CPU(32位),此时各运行一个线程
说具体点,线程1正执行写入一个Int32操作,线程2执行读取一个Int32操作,并且他们操作的是同一内存区域
在单线程中,同一时刻,单条指令永远只会在一个线程中执行,不可能同时在两个线程中执行

那在双核CPU中,各有一个线程,并且同时执行这下面两条指令时,是怎么保证线程同步的呢?
线程1:mov dword ptr [ebp-40h],12345678h //写入
线程2:mov  ecx,dword ptr [ebp-40h] //读取

我老是听到同样的说明:“这是由于硬件实现的锁和仲裁机制”这句话怎么理解呢?

是不是硬件中有一个缓冲区,当即使两条指今同时在CPU执行,但指令到达硬件(内存)时,还是会维护一个运行时序,还是有一个先后顺序的,当一个指令执行时,会存在一个Memory Barrier的机制,来保护执行的内存,另一条指令在硬件中会有一个类似阻塞效果的空转操作呢?

不好意思,由于我是一个菜鸟,可能表达的不清楚,期待你的回答,谢谢! --------------------编程问答-------------------- 两位大神,人呢,求解答呀?后悔以前计算机组成原理和操作系统没好好学呀 --------------------编程问答-------------------- 访问一个内存地址和读写一个硬盘数据是一样的,这部分是硬件IO的限制,
一次只能进行一个操作,同时到达的请求会排队完成。
--------------------编程问答-------------------- 脏读是件很麻烦的事,要么锁,要么多次确认。最好的方法是每个线程的空间是独立的,尽量减少这种数据交互。在设计时,就应该考虑到这种情况,如果发生了不能造成严重的错误,才是最好的选择。 --------------------编程问答-------------------- 线程是程序级别的东西。扯不上CPU核心、数量的。

“两个线程分别在两个CPU中运行”这种理解方式有误。
对于程序而言,无论CPU多核心还是多个物理CPU,统一称为 CPU资源,比较好理解。 --------------------编程问答-------------------- CPU一般只是提供信号量类似的同步指令保证原子操作,是否需要保护内存一般来说写程序的人去考虑的。 --------------------编程问答--------------------
引用 11 楼 runliuv 的回复:
线程是程序级别的东西。扯不上CPU核心、数量的。

“两个线程分别在两个CPU中运行”这种理解方式有误。
对于程序而言,无论CPU多核心还是多个物理CPU,统一称为 CPU资源,比较好理解。

比较同意楼上说法。
我们这里的编程,是不必考虑这种硬件层面如何实现的问题的。假如把这类硬件如何实现以及实现的质量等等问题都交给c#程序员,那windows操作系统还有什么价值?bios是不是也可以扔了?
考虑任何问题都应该有一定的前提条件,这才是正确的逻辑。 --------------------编程问答--------------------
引用 8 楼 u011964267 的回复:
两位大神,人呢,求解答呀?后悔以前计算机组成原理和操作系统没好好学呀


跟这个没有关系。貌似好像很接近硬件似地,反而没用。

你说的“在单核CPU中,由于在某个时刻,只有一个线程执行,因此对于一些原子操作,永远不会在两个线程拥有”,你纠结这些所谓的“原子操作”有什么编程意义?

在单核CPU时,如果你看看windows系统,也会同时有几百个线程在运行。因此就算是只在一个单核CPU的电脑上,多线程编程也需要面对现实去进行所谓的同步。不是什么想当然地用“原子操作”这个词儿糊弄自己。

你编写多线程程序,不管计算机有几个核心,所谓的线程同步都是完全一样的写法。

我不打算回答你的问题。因为你的概念决定了你无法听懂结果。 --------------------编程问答-------------------- 你实际上一开口提出问题的时候,你的“论据”就出现了严重的概念性问题。你此时说什么“多核、单核”,根本没有必要。 --------------------编程问答-------------------- 你所谓的“原子操作”,就算是你有1000个核心,它对于一台计算机(的体系结构设计而言)也是运行时的一个原子操作,根本纠结不到“单核、多核”。抛去这个胡乱引用的词儿,再看一遍你的“论据”,那么那种混乱就很明显了。

就算是只有一个CPU核心,对于抢先式多任务的windows系统而言,每隔几十毫秒就会切换到其它线程,因此线程“同步”是由于逻辑控制需求造成的。

怎么可能简单地说是什么“单核、多核”造成的? --------------------编程问答--------------------
引用 15 楼 sp1234 的回复:
你实际上一开口提出问题的时候,你的“论据”就出现了严重的概念性问题。你此时说什么“多核、单核”,根本没有必要。



 装13


单核CPU因为任何时刻都只能有一条指令,原理上不存在需要锁,但操作系统采用可抢占式时间轮片调度的方式,有可能造成某个线程在进入某块临界区代码时是抢占了,所以提供了一个标志锁。

多核在任何时刻都可以有一条以上的指令在同步执行,这个必须要用到锁。我知道的方式是关中断,然后锁数据总线,利用汇编xchg指令的原子性实现自旋锁。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,