单核下 一个 CPU 核执行并发,在微观上来看还是串行的 这样是不是不会导致”线程不安全“? 只有多核并发才会导致线程不安全?
1
mokeyjay 2017-06-26 11:42:52 +08:00 via Android 4
…你是不是没有搞懂线程和并发的区别?
|
3
bazingaterry 2017-06-26 12:00:39 +08:00 via iPhone
锁这玩意,可比多核 CPU 早设计出来...
|
4
hjc4869 2017-06-26 12:00:58 +08:00 via Android
会,你的非线程安全的代码执行了一半,这时一个时钟中断信号来了,切到别的线程去了,然后另一个线程就把你这个线程用的变量破坏了
|
5
clearbug 2017-06-26 12:01:49 +08:00 via Android
啥是并发?
啥是并行? 啥是线程安全? 楼下来解释 |
6
zwzmzd 2017-06-26 12:05:39 +08:00 via iPhone
单核异步?所有代码块都是先后执行的,不存在同时执行两个代码块的问题,块内不用考虑线程安全问题。
但实际中,为了性能考虑代码块的粒度都会尽量的小,还是会碰到相似问题 |
7
zwzmzd 2017-06-26 12:08:00 +08:00 via iPhone
@zwzmzd 发现看错题意了。
即使单 cpu,操作系统也会按时间分片模拟出多核并发的效果,所以假设是不成立的 |
8
maxxxxx 2017-06-26 12:08:25 +08:00 via iPhone
实际上很多下游开发者是没有多核概念的。
|
9
Lonely 2017-06-26 12:53:11 +08:00
去搞清楚概念再来,好吗?
|
10
wwqgtxx 2017-06-26 13:40:09 +08:00 via iPhone
除非你的单核并发是不允许抢占式的,否则一样会产生线程不安全
举个简单的例子,程序 1 执行 i++,程序 2 也执行 i++ 当程序 1 将 i 值读取出来并运算后改为写入的时候,系统抢占式把控制权给个程序 2,程序 2 完整的执行完了 i++,随后系统将控制权交回给程序 1,此时的程序 1 并不知道自己被打断了,也不知道 i 已经被修改,还把之前计算好的值写入,最后结果就是 i 只加了 1,而不是加了 2 |
11
momocraft 2017-06-26 13:51:49 +08:00
如果你不做保证线程安全的事,就没什么东西是线程安全
|
12
hand515 2017-06-26 13:57:33 +08:00
无法保证一段代码执行的原子性
|
13
gogohigh 2017-06-26 14:02:56 +08:00
Concurrent 和 Parallel 是两个概念
|
14
SKull4 2017-06-26 14:09:32 +08:00
应该不是科班的
|
15
blackjar 2017-06-26 14:56:48 +08:00
你应该是混淆了并发跟并行 并发在只是 cpu 时序有交叉
|
16
facetest 2017-06-26 15:46:08 +08:00
建议先补补基础知识
|
17
20015jjw 2017-06-26 18:06:42 +08:00 via Android
@wwqgtxx 两个程序之间不能互相 access 内存吧 操作系统的虚拟内存不就 是为了避免这件事情发生的吗...
|
18
yushiro 2017-06-26 18:39:15 +08:00 via iPhone
@20015jjw 同一个程序的不同代码块可以啊,比如电子商城购买虚拟物品,同时扣款的例子,就是那个 i++的实际案例
|
19
stephenyin 2017-06-26 18:53:31 +08:00
@20015jjw 考虑单进程多线程的情况!
|
22
honeycomb 2017-06-26 19:27:02 +08:00 via Android
单核不会出现 CPU 缓存不一致的情况,因为只有一个 CPU 核心。
|
23
20015jjw 2017-06-26 19:51:06 +08:00 via Android
@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 的吧 但是感觉可能是违背操作系统设计规范的... |
24
kaneg 2017-06-26 20:05:17 +08:00 via iPhone
单核线程冲突的概率应该会小一些,但不会消失,毕竟不是原子性的操作会有可能被分配到 CPU 的两个时间片被两个线程分别抢占。
其次,在多核 CPU 出现之前多线程的同步问题就出现了。 |
28
powergx 2017-06-26 20:59:22 +08:00
你只要保证你的内存地址数据不会被篡改,100/1000 个线程 都是安全的
|
29
situliang 2017-06-26 21:09:10 +08:00
是时候补习一波操作系统了
|
30
yushiro 2017-06-26 21:41:33 +08:00 via iPhone
@20015jjw 不同的 process 的确如你所说,但是 web server 是同一个 process 处理大量请求(同一个域名站点),所以会发生我说的情况
|
31
mazyi 2017-06-27 00:17:11 +08:00 via iPhone
2333,看书去
|
33
msg7086 2017-06-27 01:03:08 +08:00
不管操作系统怎么保护内存,也有可能两个程序读写同一个文件造成线程不安全的。
|
34
hjc4869 2017-06-27 01:38:27 +08:00 via Android
@20015jjw 并没有,因为共享内存之后两个进程的地址空间仍然是独立的,虚拟内存的定义并没有规定物理页一定被某个地址空间独占。
|
35
20015jjw 2017-06-27 02:57:18 +08:00 via Android
@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 由于虚拟内存的关系 在实际内存中的位置不一样 |
36
hjc4869 2017-06-27 04:24:44 +08:00 via Android
@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 |
37
wwqgtxx 2017-06-27 07:16:19 +08:00
@20015jjw 只能说你看的“操作系统设计规范”可能已经过时了,在实际工作中,进程直接 share memery 是非常常见的事情,有些高级语言甚至直接在标准库中提供了接口,比如 Python 的 multiprocessing.Value, multiprocessing.Array 都可以直接直接在两个或者多个进程直接直接共享同一块内存,以减小本机程序之间 RPC 调用带来的不必要的性能损耗
|
38
wwqgtxx 2017-06-27 07:20:14 +08:00
而且两个进程直接会产生线程不安全的情况并不是只有同时读写同一块内存区域这一种,如果同时读写同一个 FILE,或者同时读写同一个 MMAP 分配的空间,同时读写一个共享的 socket 都可以造成线程不安全,以及父进程和子进程同时读写同一个打开的句柄或者管道
|
39
icegreen 2017-06-27 10:10:34 +08:00
收获一枚面试题~
|