python并發編程之多線程

多線程

線程

1.什么是線程

  • 進程是一個執行空間 , 線程就是其中真正工作的單位 , 每一個進程至少有一個線程(如果我們把操作系統比喻為一個工廠 , 進程就是車間 , 線程就是流水線)

進程包含了運行該程序所需要所有資源 , 進程是一個資源單位 , 線程是CPU的最小執行單位

每一個進程一旦被創建 , 就默認開啟了一條線程 , 稱之為主線程

2.為什么使用線程

  • 多線程指的是,在一個進程中開啟多個線程,簡單的講:如果多個任務共用一塊地址空間,那么必須在一個進程內開啟多個線程。詳細的講分為4點:

    1. 多線程共享一個進程的地址空間

    1. 線程比進程更輕量級,線程比進程更容易創建可撤銷,在許多操作系統中,創建一個線程比創建一個進程要快10-100倍,在有大量線程需要動態和快速修改時,這一特性很有用

    1. 若多個線程都是CPU密集型的,那么并不能獲得性能上的增強,但是如果存在大量的計算和大量的I/O處理,擁有多個線程允許這些活動彼此重疊運行,從而會加快程序執行的速度。

    1. 在多CPU系統中,為了最大限度的利用多核,可以開啟多個線程,比開進程開銷要小的多。(這一條并不適用于python)

使用線程可以提高程序效率

為何不用多進程提高效率 : 是因為進程對操作系統的資源耗費非常高

3.線程與進程的區別:

  1. 線程共享創建它的進程的地址空間 ; 進程有自己的地址空間。

  2. 線程可以直接訪問其進程的數據段;進程擁有自己父進程數據段的副本。

  3. 線程可以直接與其進程的其他線程通信;進程必須使用進程間通信來與兄弟進程通信。

  4. 新線程很容易創建;新流程需要復制父流程。線程可以對同一進程的線程進行相當大的控制;進程只能控制子進程。對主線程的更改(取消,優先級更改等)可能會影響進程的其他線程的行為;對父進程的更改不會影響子進程。

4.什么時候開啟多線程

  • 當程序中遇到IO操作時(當程序中時純計算任務時 也無法提高效率)

5.如何使用

  • from threading import Thread

創建線程與創建進程的方式幾乎一樣 , 但是創建子進程會將父進程的資源復制執行一遍 , 所以必須在__main__下執行 , 而創建線程則不一樣 , 線程間共享進程資源,所以不需要復制執行父線程代碼,所以可以不加__main__

一 . 創建線程的兩種方式

  1. 調用類型

from threading import Thread
?
?
def task():print('thread running...')
?
?
if __name__ == '__main__':t = Thread(target=task)t.start()
?print('主線程')
?
# 執行結果
# thread running...  (子線程比主線程執行速度更快)
# 主線程
  1. 繼承類型

from threading import Thread
?
?
class Sayhi(Thread):def __init__(self,name):super().__init__()self.name=namedef run(self):print('%s say hello' % self.name)
?
?
if __name__ == '__main__':t = Sayhi('jason')t.start()print('主線程')# 執行結果
#jason say hello
#主線程

?

二 . 線程的常用方法

Thread實例化對象的方法:
# 1.isAlive():      判斷線程是否還存在(未終止)
# 2.getName():      返回線程名
# 3.setName():      設置線程名
?
threading模塊下提供的方法
# threading.currentThread():        返回當前的線程變量
# threading.enumerate():        返回一個正在運行的線程列表
# threading.activecount():      返回當前運行的線程數量
# len(threading.activecount()):     與上一個方法返回相同值

?

三 . 在一個進程下開啟多個線程與在一個進程下開啟多個子進程的區別

  1. 開啟速度 : 開啟線程>>開啟進程(所以程序效率會大大提高)

  2. id :

    • 進程開啟多線程的pid都相同 ( 很好理解pid是process id , 所以線程pid相同)

    • 進程開啟多個進程的pid不同

  3. 空間資源:

    • 進程開啟的多線程的共享進程內的資源 , 某線程修改數據后 . 其他線程再訪問則是新的數據

    • 進程開啟多個子進程的數據互相獨立 , 子進程內修改數據不會對其他進程數據造成干擾

?

守護線程

守護線程(setdaemon)

  • 守護線程 : 守護線程會在所有非守護線程結束后結束

    守護線程本質是上是在守護主線程 ,但是對于主線程來說 , 運行完畢指的是主線程所在的進程內所有非守護進程統統運行完畢,主線程才算運行完畢

from threading import Thread
import time
?
def task1():print('sub thread is running...')time.sleep(0.5)print('sub thread end...')
def task2():time.sleep(0.1)print('task2 is run...')
?
t1 = Thread(target=task1)
t2 = Thread(target= task2)
?
t1.setDaemon(True)  # 將t1設置為守護線程, 必須在start之前設置
?
t1.start()
t2.strat()
?
# 執行結果
#sub thread run...
#task2 is run...
?
?

?

線程互斥鎖(Lock)

  • 什么時候用鎖 :

    當多個進程或多個線程需要同時修改同一份數據時,可能會造成數據錯亂,所以必須加鎖

import time
from threading import Thread,Lock
?
lock =Lock()  # 實例化鎖對象
?
a = 100
?
def task():lock.acquire()  # 給線程上鎖global a  # 訪問全局atemp = a - 1  # 修改全局atime.sleep(0.01)a = templock.release()   # 釋放鎖,線程執行完畢
?
ts = []
for i in range(100):t = Thread(target=task)t.start()ts.append(t)
?
for t in ts:  # lock保證了多線程串行,同時主線程print(a)也在其中,但是我們想得到最終結果,所以用join人為設置順序
    t.join()
?
?
print(a)

信號量(Semaphore)

信號量:

  • 其實也是一種鎖 , 特點是可以設置一個數據可以被幾個線程(進程)共享.

    與普通鎖的區別:

    • 普通鎖一旦加鎖,則意味著這個數據在同一時間只能被一個線程使用

    • 信號量這種鎖,特點是可以設置一個數據可以被幾個線程(進程)共享

  • 使用場景

    • 可以限制一個數據同時訪問的次數 , 保證程序正常運行

from threading import Thread,Semaphore
import time
sem = Semaphore(3)  # 設置最大訪問進程數
?
?
def task():sem.acquire()print('你好啊')time.sleep(3)sem.release()
?
?
for i in range(10):t = Thread(target=task)
?t.start()# 執行結果太長, 就不打印了
# 現象描述 : 就是3個一次打印

守護進程的使用

"""
用生產者消費者模型實現一個顧客吃漢堡的功能
主要是生產者生產處漢堡放入隊列,然后消費者吃掉,
要判斷什么時候顧客吃完了所有生產了的漢堡
"""
from multiprocessing import Process, JoinableQueue
import time, random
?
def eat_hotdog(name, q):while True:res = q.get()print('%s吃了%s' % (name,res))time.sleep(random.randint(1,2))q.task_done()
?
?
def make_Hotdog(name, q):for i in range(1,6):time.sleep(random.randint(1,2))print('%s生產了第%s個熱狗' % (name, i))res = '%s的%s個熱狗' % (name,i)q.put(res)
?
?
if __name__ == '__main__':q = JoinableQueue()
?#生產者c1 = Process(target=make_Hotdog, args=('a熱狗店', q))c1.start()
?#生產者2c2 = Process(target=make_Hotdog, args=('b熱狗店',q))c2.start()
?# 消費者p2 = Process(target=eat_hotdog, args=('顧客',q))p2.daemon = True  # 隊列阻塞打開,主進程執行完畢,守護進程死
    p2.start()
?
?# 保證生產者全部完成
    c1.join()c2.join()
?
?# 保證隊列中的數據全部被處理了'''join:阻止,直到隊列中的所有項目都已獲取并處理完畢。
?每當項目添加到隊列時,未完成任務的計數就會增加。 每當消費者調用task_done()以指示該項目已被檢索并且其上的所有工作都已完成時,計數就會下降。 當未完成任務的數量降至零時,join()取消阻塞。'''q.join()  # JoinableQueue方法

?

轉載于:https://www.cnblogs.com/liusijun113/p/10211715.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/449870.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/449870.shtml
英文地址,請注明出處:http://en.pswp.cn/news/449870.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JavaScript幾個難點

1. 立即執行函數 立即執行函數,即Immediately Invoked Function Expression (IIFE),正如它的名字,就是創建函數的同時立即執行。它沒有綁定任何事件,也無需等待任何異步操作: (function() { // 代碼 // ...})(); f…

真格量化學習

真格量化學習使用 期權的量化回測 引入必須的庫: from PoboAPI import * import datetime import time import numpy as np初始化參數設定 以50為例 def OnStart(context) :print("I\m starting...")#設定一個全局變量品種,本策略交易50ETF期權g

智能小程序檔案館——如何給“包”瘦身

上傳小程序代碼的時候包體積太大不知如何是好?小程序打開速度慢,流量耗費大不知如何優化?在今天的文章里,我們一起來討論一下如何給“包”瘦身。 為什么要限制包的大小? 我們都知道小程序作為一種 Hybrid 的解決方案&a…

軟件架構師的能力與特質

軟件開發工程師的職業發展無非兩大類:一是做“官”,從事管理工作;二則繼續從事技術工作。對于后者,軟件架構師(software architect)是很多軟件開發工程師追求的理想崗位。在這我想談一談軟件架構師所需的幾…

IntelliJ IDEA編碼設置

見:https://www.cnblogs.com/winner-0715/p/6364306.html項目中為了避免亂碼等問題應該使用UTF-8編碼方式,其實把編碼方式設置成UTF-8是創建完項目后就要做的事,按照如圖所示進行設置:這里要將Transparent native-to-ascii conversion選項勾選, 否則項目…

C#實現像微信PC版一樣的掃碼登錄功能

現在好些網站都支持掃碼登錄,感覺上安全了很多,但是本地程序掃碼登錄的不多,就用C#實現了一下,需要作如下準備 在官網上申請一個企業微信,有條件的話做個企業認證吧,我們的是認證過的,所以賬號和本地其他系統的賬號是統一的.在應用中創建一個應用,這個是關鍵,我們掃碼就是和它有…

JVM(一)史上最佳入門指南

2019獨角獸企業重金招聘Python工程師標準>>> 提到Java虛擬機(JVM),可能大部分人的第一印象是“難”,但當讓我們真正走入“JVM世界”的時候,會發現其實問題并不像我們想象中的那么復雜。唯一真正令我們恐懼的…

如何成為一個技術“牛人”

今天給浙江大學過來的幾個還沒有畢業的研究生做面試,這些研究生是想來公司實習的。在面試的過程中,一個學生問我“我們有C/C、JAVA等等多種語言,我如何才能成為某一方面的一個技術牛人呢?這一問題一直困擾著我”,對于這…

python量化數據處理小細節(以后還會不斷補充)

使用tushare數據源獲取數據后處理 以下都是本人在獲得數據后,進行量化回測時,處理數據遇到的各種坑以及解決方案,有些甚至都很幼稚,切勿嘲笑 獲取數據 導包 import tushare as ts import pandas as pd import matplotlib #(ju…

Linux find和grep的區別

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 grep是查找文件中匹配條件的行,find是搜索匹配條件的文件。 1.find:查找文件或目錄語法: find 查找位置 文件名或目錄名如:在…

Mysql 忘記密碼重置教程

https://jingyan.baidu.com/article/454316ab4e9e65f7a7c03ad1.html 百度經驗轉載于:https://www.cnblogs.com/leaf-cq/p/10410694.html

067:【Django數據庫】ORM查詢條件詳解-range

【Django數據庫】ORM查詢條件詳解-range range:判斷某個 field 的值是否在給定的區間中。示例代碼如下: # views.py文件內容:from datetime import datetime from django.utils.timezone import make_awaredef index(request):start_time ma…

貼吧爬蟲

import requests import re#根據url獲取網頁html內容 def getHtmlContent(url):page requests.get(url)return page.texthtml getHtmlContent(https://tieba.baidu.com/p/4840106397)#以html中使用re模塊解析出所有jpg圖片的url #百度貼吧html中jpg圖片的url格式:…

別把自己變成了“二等公民”

上周參加一個代碼審查會,在會上發現了設計上的一個很嚴重的錯誤。于是,我提了好幾個問題,想知道為什么會出現這一錯誤。但是,我的同事告訴我這都是印度團隊做的設計。需要提供的一個背景信息是,這個項目是我所在的研發…

jquery函數加載及生成隨機數

$(document).ready(function () {var code ; //在全局定義驗證碼  1.將函數寫好 function createCode(){code "";var codeLength 4;//驗證碼的長度var checkCode document.getElementById("code");var random new Array(0,1,2,3,4,5,6,7,8,9,A,B,C…

rsync解說

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 一、簡介1、認識Rsync(remote synchronize)是一個遠程數據同步工具,可通過LAN/WAN快速同步多臺主機間…

關于java中getClass()和getSuperClass()的講解

為了講解這個問題,我們先來看一下下面的代碼: package com.yonyou.test;import java.util.Date;class Test extends Date{private static final long serialVersionUID 1L;public static void main(String[] args) {new Test().print();}public void print(){Syste…

期權回測框架設計思路

期權回測,博主已經研究了很長時間,也接觸了不少平臺,如真格,以及這位博主提供的思路(https://blog.csdn.net/luoqingyong/article/details/107523930),利用backtrader進行期權回測。確實國內做期…

UVA815

這道題主要學到的就是數據結構的組織,一些需要從小到大排列的東西,這些東西還有對應的東西。這個時候使用map可以解決 下面貼出代碼。其中所使用的思想,估計這個東西是沒法學的,這就只能是靈感 //這是什么吉爾題,題意都…

我對應聘者的面試原則

最近參與了幾次單位招聘面試工作,在面試工程師時,我是用我的分層準則指導與候選人的交流內容,以確定他的能力層次是否達到我所期望的。大體上軟件工程師可以分為三大層次,分別是技術知識積累層、掌握設計方法層以及運用開發方法論…