淺談線程與線程池應用場景


什么是線程

簡述:
線程是操作系統能夠進行調度的最小單位。它運行於進程中。進程將資源整合在一起,以供線程使用。

為什么要有線程

創建線程的開銷遠小於進程

進程和線程的區別

1. 線程共享創建它的進程的地址空間;過程有它們自己的。地址空間
2. 線程可以直接訪問其進程的數據;進程有自己的父進程數據段的副本。
3.線程可以直接與進程中的其他線程通信;進程必須使用進程間通信來與同級進程通信
4. 新線程很容易創建;新的進程需要父進程的復制。
5. 線程可以對同一進程的線程進行相當大的控制;流程只能對子流程進行控制。6. 主線程的更改(取消、優先級更改等)可能會影響進程中其他線程的行為;對父進程的更改不會影響子進程。
不同進程間是充滿敵意的,彼此是搶占,競爭cpu的關系;例如:酷狗會和mysql搶占資源。 
不同線程之間是數據共享的是合作關系,一個線程可以訪問另外一個線程的內存地址

為何要用多線程(線程對比進程的好處)

1.多線程共享一個進程的地址空間。線程之間數據共享
2.線程比進程更輕量級,線程比進程更容易創建並且可以撤銷。創建線程耗時是進程的十分之一到百分之一
3.如果使用多線程是cpu密集型的,那么不能獲得性能上的增加,但是如果線程處理大量I/O操作,多線程可以節約時間,加快程序執行的速度
4.在多cpu的系統中(現在電腦多為多cpu),為了最大限度利用多核,可以開啟多個線程並且比進程開銷小很多(cpython不適用,GIL鎖)

線程的問題

線程通常是有益的,但是帶來了不小程序設計難度,線程的問題是:

  1. 父進程有多個線程,那么開啟的子線程是否需要同樣多的線程

   如果是,那么附近中某個線程被阻塞,那么copy到子進程后,copy版的線程也要被阻塞嗎,想一想nginx的多線程模式接收用戶連接。

  2. 在同一個進程中,如果一個線程關閉了問題,而另外一個線程正准備往該文件內寫內容呢?

          如果一個線程注意到沒有內存了,並開始分配更多的內存,在工作一半時,發生線程切換,新的線程也發現內存不夠用了,又開始分配更多的內存,這樣內存就被分配了多次,這些問題都是多線程編程的典型問題,需要仔細思考和設計。

使用線程池如何設計IO密集型多線程和CPU密集型多線程

首先線程池是一種多線程處理形式,處理過程中將任務添加到隊列,然后在創建線程后自動啟動這些任務。如果所有線程池線程都始終保持繁忙,但隊列中包含掛起的工作,則線程池將在一段時間后創建另一個輔助線程但線程的數目永遠不會超過最大值。超過最大值的線程可以排隊,但他們要等到其他線程完成后才啟動。

正是因為線程池的這些特點,當我們需要初始化一個線程池時,就要考慮我們的線程池被用來執行什么樣的任務。

常見的任務分為兩種:CPU密集型任務和IO密集型任務

CPU密集型任務(CPU-bound):在一個任務中,主要做計算,CPU持續在運行,CPU利用率高,具有這種特點的任務稱為CPU密集型任務。
IO密集型任務(IO-bound):在一個任務中,大部分時間在進行I/O操作,由於I/O速度遠遠小於CPU,所以任務的大部分時間都在等待IO,CPU利用率低,具有這種特點的任務稱為IO密集型任務。

所以我們在設計線程池時,應先對執行的任務有個大體分類,然后根據類型進行設置。一般而言,兩種任務的線程數設置如下:

CPU密集型任務:線程個數為CPU核數。這幾個線程可以並行執行,不存在線程切換到開銷,提高了cpu的利用率的同時也減少了切換線程導致的性能損耗
IO密集型:線程個數為CPU核數的兩倍。到其中的線程在IO操作的時候,其他線程可以繼續用cpu,提高了cpu的利用率


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM