单核并发是不是不会产生"线程不安全”的问题?

2017-06-26 11:28:18 +08:00
 guyeuro

单核下 一个 CPU 核执行并发,在微观上来看还是串行的 这样是不是不会导致”线程不安全“? 只有多核并发才会导致线程不安全?

8015 次点击
所在节点    问与答
40 条回复
wwqgtxx
2017-06-26 19:17:45 +08:00
@20015jjw 第一,大量存在单进程多线程的情况,第二,还存在进程间共享内存的情况
honeycomb
2017-06-26 19:27:02 +08:00
单核不会出现 CPU 缓存不一致的情况,因为只有一个 CPU 核心。
20015jjw
2017-06-26 19:51:06 +08:00
@wwqgtxx
@hjc4869
@stephenyin
@yushiro

程序不是 process 么 thread 当然可以共享 但是不同 process 不是都是自己一个虚拟内存么... 这个帖子里就写了啊
https://stackoverflow.com/questions/11566780/process-vs-thread-can-two-processes-share-the-same-shared-memory-can-two-thr

当然我只学过简单的操作系统 想想有修改器的存在大概 process 之间肯定也能互相 access 的吧 但是感觉可能是违背操作系统设计规范的...
kaneg
2017-06-26 20:05:17 +08:00
单核线程冲突的概率应该会小一些,但不会消失,毕竟不是原子性的操作会有可能被分配到 CPU 的两个时间片被两个线程分别抢占。
其次,在多核 CPU 出现之前多线程的同步问题就出现了。
wwqgtxx
2017-06-26 20:17:25 +08:00
@20015jjw 程序是 program 进程才是 process
hjc4869
2017-06-26 20:39:26 +08:00
@20015jjw 但是同一个物理内存页可以被映射到两个不同的进程的地址空间里啊
acess
2017-06-26 20:56:38 +08:00
@20015jjw 有 WriteProcessMemory、CreateRemoteThread 等 API 可以用。
powergx
2017-06-26 20:59:22 +08:00
你只要保证你的内存地址数据不会被篡改,100/1000 个线程 都是安全的
situliang
2017-06-26 21:09:10 +08:00
是时候补习一波操作系统了
yushiro
2017-06-26 21:41:33 +08:00
@20015jjw 不同的 process 的确如你所说,但是 web server 是同一个 process 处理大量请求(同一个域名站点),所以会发生我说的情况
mazyi
2017-06-27 00:17:11 +08:00
2333,看书去
20015jjw
2017-06-27 00:59:34 +08:00
@hjc4869 这不就违背了虚拟内存的定义么...
msg7086
2017-06-27 01:03:08 +08:00
不管操作系统怎么保护内存,也有可能两个程序读写同一个文件造成线程不安全的。
hjc4869
2017-06-27 01:38:27 +08:00
@20015jjw 并没有,因为共享内存之后两个进程的地址空间仍然是独立的,虚拟内存的定义并没有规定物理页一定被某个地址空间独占。
20015jjw
2017-06-27 02:57:18 +08:00
@hjc4869 对 但是系统会控制不让一段物理内存被俩程序同时使用啊 http://www.read.seas.harvard.edu/~kohler/class/05s-osp/notes/notes9.html 注意粗体
> The different processes' memory spaces must be isolated from each other, and from the kernel.
我 os 课的理解就是 虽然每个 process 看内存都是和系统内存一样大的 比如 0x0000-0xffff 但是俩程序不用满整个系统内存的时候 俩程序所占内存的真实地址永远不会重叠 即便在他们自己眼中可能都在 0x00ff 的地方写东西 但是这俩 00ff 由于虚拟内存的关系 在实际内存中的位置不一样
hjc4869
2017-06-27 04:24:44 +08:00
@20015jjw 我没说地址空间自己会重叠,我指的是现代 OS 在进程主动要求的前提下 OS 会允许两个独立的进程将同一部分物理内存页映射到它们各自的地址空间内。这个叫做 shared memory,是一类非常常用的跨进程通讯手段,通常搭配其它同步、互斥方式,在对数据交换有非常高的性能要求时会使用。比如 Linux 下的 X11,在本机就是使用 MIT-SHM 扩展,利用共享内存交换数据,其原理就是将相同的物理内存页同时映射到多个进程的地址空间。

因此上面说的跨进程 i++问题是可能存在的

具体的 API 参考:
Windows: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx
Linux: http://man7.org/linux/man-pages/man7/shm_overview.7.html
wwqgtxx
2017-06-27 07:16:19 +08:00
@20015jjw 只能说你看的“操作系统设计规范”可能已经过时了,在实际工作中,进程直接 share memery 是非常常见的事情,有些高级语言甚至直接在标准库中提供了接口,比如 Python 的 multiprocessing.Value, multiprocessing.Array 都可以直接直接在两个或者多个进程直接直接共享同一块内存,以减小本机程序之间 RPC 调用带来的不必要的性能损耗
wwqgtxx
2017-06-27 07:20:14 +08:00
而且两个进程直接会产生线程不安全的情况并不是只有同时读写同一块内存区域这一种,如果同时读写同一个 FILE,或者同时读写同一个 MMAP 分配的空间,同时读写一个共享的 socket 都可以造成线程不安全,以及父进程和子进程同时读写同一个打开的句柄或者管道
icegreen
2017-06-27 10:10:34 +08:00
收获一枚面试题~
20015jjw
2017-06-27 15:35:26 +08:00
@wwqgtxx 嘛 入门课 我也知道有 process 之间分享内存的 只是老师表示这个课不考虑 谢谢你提供的知识啦

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/371095

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX