国际化与多线程

Posted 国际化梦工厂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了国际化与多线程相关的知识,希望对你有一定的参考价值。

提到开发中的多线程问题,我想大部分人并不陌生,其中有不少兄弟还能津津乐道于生产者,消费者模型,做烤鸭吃烤鸭的案例也烂熟于心。不过要是谈到多线程跟国际化有啥关系时,相信多数人还是会语塞,其实我也一样,从未认为国际化问题跟多线程能扯上什么关系。直到最近碰到了这样的几个bug,算是“活久见”系吧。


在一个产品的UI上,慕然发现大部分内容显示中文字符(这是期望结果),但就在同一页面上某几个label还有零星选项居然显示为日文,注意!不是英文,绝非hardcode哦。(screenshot太敏感,就不贴出来了)


这是为啥呢?莫非中文的资源文件中包含了日文?因为翻译的一个简单疏漏所导致?那就查查看呗,结果发现所有资源问题静静的躺在那里,一点儿瑕疵也没有啊。那只好再看看产品代码是如何读取locale并更新l10nstring的吧。

定位代码如下:(仅用于示意)

可以看到test.py使用@classmethod UpdateLocale在查询前设置当前locale。如果我们假定在同一时间内只有一个用户使用,那么该方法就可以确保从客户端获取语言环境没有任何错误。但考虑到现实业务背景,则不同的客户在同一时间运行后端线程并更新locale的情况是完全可能的情况,而在此时使用class method更新locale则将很可能导致locale冲突。为了还原案发现场,这里我会加入sleep()来代替真实的IO操作,修改如下。

国际化与多线程运行结果是这样的。

不难发现,UpdateLocale 之后因为进行了sleep(真实情况是在处理其他IO操作,导致有时间的latency),而正在此时,恰好有其他thread对UpdateLocale进行了调用,这就不可避免的在L10NGetHealthCheckText时产生了混乱了,最终导致用户在UI上看到部分内容是中文,而部分是日文的诡异情况。

归根结底,这种concurrency问题基本都是因为不正确的使用了共享变量而导致的,如本例中的locale。我们需要修改的则是要求每次调用L10NGetHealthCheckText的相关方法时,都传入locale,而不是对UpdateLocale这样class method的一次调用,就像这样。

以上是关于国际化与多线程的主要内容,如果未能解决你的问题,请参考以下文章

QtConcurrent 与多线程 QThread 的多线程性能

python多进程与多线程使用场景

多线程与多进程

多进程(mutiprocessing)与多线程(Threading)之多线程

泥瓦匠聊并发编程:线程与多线程必知必会(基础篇)

并发编程:线程与多线程必知必会