两个问题。多线程操作 UI 为什么不可行?为什么 UI 线程必为主线程?

2018-01-03 16:02:04 +08:00
 chipmuck

第二个问题我解释一下,意思就是:大多数程序语言都把 UI 线程定在主线程上,那为什么不能将 UI 单独拿出来放到一个独立的子线程上进行操作?其中有啥玄学呢?

9064 次点击
所在节点    iDev
24 条回复
gesse
2018-01-03 16:08:29 +08:00
UI 当然要用单线程,多线程操作你想让 UI 在同一时刻呈现不同的样子?

至于为什么放主线程,感觉应该是主线程按理说应该更加不容易『卡死』,让你把复杂数据、网络等操作放到子线程,『默默』处理好了以后,把结果呈现给 UI 就可以了。
InternetExplorer
2018-01-03 16:15:11 +08:00
多线程操作 UI 会导致 UI 进入叠加态,人作为观察者观察 UI 则会使 UI 坍缩到某一具体的形态,为了避免这种不确定性,所以只用一个线程操作 UI (雾
TestSmirk
2018-01-03 16:17:30 +08:00
多线程操作 UI emmm,你见过 gif 图吧..
piaochen0
2018-01-03 16:19:06 +08:00
在一般的 UI 系统中,UI 的生成,渲染永远运行在主线程中的...其他线程和主线程是平行状态...
chipmuck
2018-01-03 16:22:50 +08:00
@piaochen0 这是系统设计的原因吗?
chipmuck
2018-01-03 16:24:06 +08:00
@InternetExplorer
@TestSmirk

多线程操作 UI 的问题没啥疑问的,关键是第二个问题。。
alqaz
2018-01-03 16:32:12 +08:00
在很久以前,没有多线程,可能是为了兼容性;还有,别人不想用多线程的情况下那怎么难道系统还要默认额外开一个线程给它?瞎猜的。
deadEgg
2018-01-03 16:34:47 +08:00
回答第二个问题:

当有子线程,主线程和子线程地位相同,不会因为主线程死亡而进程死亡

猜测 ui 线程放到主线程有两个原因:
1. ui 初始化做的工作比较多,如果不是主线程,启动子线程需要资源和时间,ui 启动慢
2. 更新 ui 需要在 ui 线程,如果非主线程那你每次更新 ui 都要进行线程通信( android 为例,setXXX 就要通信一次,速度堪忧)

主要想到这两个原因,望指正
piaochen0
2018-01-03 16:41:38 +08:00
我的理解是,
1.作为一个有界面的系统,最基本解决的问题是:UI,用户的输入。假如是你自己从最底层来设计这套系统,是不是考虑在主线程运行优先级最高的选项?两者属于比较底层和基础的功能。而且确实也没太必要引入其他线程,毕竟线程引入也需要开销。更何况,很多系统或者系统的早期,也不支持多线程,或者支持的不太好。
2.UI 的渲染在某些软硬件系统中,其实是资源消耗很严重的操作,假如任用多个线程随意操作,会很影响性能吧。
nybux
2018-01-03 16:44:54 +08:00
其实核心的问题是消息循环,对于直接涉及到底层的语言,是可以的,windows 程序,gtk,完全可以把消息循环放在其他线程里面。甚至 UI 操作不要求一定要在特定线程里面。但是一旦涉及到框架。比如 MFC/QT/SWT。为了使用方便,不阻塞 UI,避免让使用者了解过多的线程细接。所以,就把 ui 操作强制放到某个线程中了。
am241
2018-01-03 16:48:09 +08:00
ui 和游戏有点像,输入 计算 渲染的循环
whileFalse
2018-01-03 16:52:06 +08:00
UI 当然可以是子线程。主线程还是子线程主要看模型。

对于 iOS 开发来说,UI 是主要的,后台线程是为了加速 UI 线程的响应速度存在的。可以没有后台线程,不能没有 UI 线程。所以 UI 是主线程。
如果你用 python 写 UI,情况就翻过来了。python 主线程是个命令行,命令行线程再创建 UI 线程。命令行线程没有 UI 也能跑,UI 却不得不依附命令行线程。所以 UI 是子线程。
mooncakejs
2018-01-03 16:52:27 +08:00
UI 不是不可以多线程,而是多线程不可控,所以搞个单线程模型简单一点。
crysislinux
2018-01-03 16:54:30 +08:00
第二个问题,实际上很多程序是没有用多线程的,但是它们却有 gui,此时只有一个主线程,当然 ui 线程就是主线程了。所以当有多线程的时候,反正 ui 要一个线程,为何不统一用主线程呢?
momocraft
2018-01-03 17:02:24 +08:00
1 可能是因為多線程時的內存可見性問題
2 有沒有可能是人們把默認創建的給 ui 用的線程 (而不是進程初始的那個) 稱做主線程?
zhuangzhuang1988
2018-01-03 17:02:38 +08:00
第二个问题不是得比如
F#的 fsi,支持 Form 渲染,而这个 UI 线程不是主线程
shibo501c
2018-01-03 17:17:52 +08:00
之前也疑惑过,多线程开发难度大,容易死锁,Java 并发编程第 9 章有提到,和主线程对应是为了方便吧
forestyuan
2018-01-03 17:42:45 +08:00
问题有误,在 windows 下 UI 有多个线程并不罕见
nicevar
2018-01-03 17:45:47 +08:00
UI 的实际就是屏幕上贴图,就是把一个个元素绘制好然后往屏幕上贴,当然是由一个线程来管理最好了,否则非常难管理,出现一些隐藏非常深的 bug,比如一个父控件里面有多个子控件,一个线程正在遍历属性,另一个线程去移除了一个控件,这不乱套了,资源文件的加载释放处理也容易出错,早期 android 在非 UI 线程更新 UI 时不会报错的,很多初级的开发者经常写出那种在其他线程更新 UI 的逻辑,程序运行看起来很正常,一旦某个特定的情况下程序就挂了

楼主有次疑问的原因是现在的 UI 开发大多数就是在叠控件,基本上不用自己管理内存了,随便 new 对象随便加载资源,如果自己做个 UI 框架从底层开始绘制就会了解的更清楚了
fcten
2018-01-03 17:52:46 +08:00
问题不成立……没有不可行,有的只是设计者对成本与收益的权衡。

在多窗口的桌面系统中,每一个窗口绑定单独的 UI 线程,在子线程中处理 UI 都是非常常见的。

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

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

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

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

© 2021 V2EX