单进程,单线程:一个人在一个桌子上吃菜
单进程,多线程:多个人在同一个桌子上一起吃菜
多进程,单线程:多个人每个人在自己的桌子上吃菜。
多线程的问题是多个人同时吃一道菜的时候容易发生争抢。例如,同一个单位的两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了。此时就必须等一个人夹一口之后,再给另外一个人夹菜,也就是说资源共享就会发生冲突争抢。
对于 Windows 系统来说,开桌子的开销很大,因此 Windows 鼓励大家在一个桌子上吃菜。因此 Windows 多线程学习重点是要大量面对资源争抢与同步方面的问题。
对于 Linux 系统来说,开桌子的开销很小,因此 Linux 鼓励大家尽量每个人都开自己的桌子吃菜。带来新的问题就是,坐在两张不同的桌子上的同事,说话不方便。因此Linux 下的学习重点大家要学习进程间通讯的方法。
有人对这个开销很有兴趣。我把这个问题推广说开一下。
开桌子的意思是指创建进程。开销这里主要指的是时间开销。
做个实验:创建一个进程,在进程中往内存写若干数据,然后读出该数据,然后退出。此过程重复 1000 次,相当于创建/销毁进程 1000 次。在我机器上的测试结果是:
UbuntuLinux:耗时 0.8 秒
Windows7:耗时 79.8 秒,两者开销大约相差一百倍。
这意味着,在 Windows 中,进程创建的开销不容忽视。换句话就是Windows编程中不建议你创建进程,如果你的程序架构需要大量创建进程,那么最好是切换到 Linux 系统。
大量创建进程的典型例子是服务器,某些服务器框架依靠大量创建进程来干活,甚至是对每个用户请求就创建一个进程,这些服务器在 Windows下运行的效率就会很差。这"可能"也是放眼全世界范围,Linux 服务器远远多于 Windows 服务器的原因。很多人答案说的是操作系统提供的多进程而不是单个程序内的多线程。
多线程使得程序内部可以分出多个线程来做多件事情,而不会造成程序界面卡死。
比如迅雷等多线程下载工具就是典型的多线程:一个下载任务进来,迅雷把文件平分成10份,然后开10个线程分别下载。这时主界面是一个单独的线程,并不会因为下载文件而卡死。而且主线程可以控制下属线程,比如某个线程下载缓慢甚至停止,主线程可以把它强行关掉并重启另外一个线程。