併發編程之——多線程基礎

  1、一些概念多線程

  線程,顧名思義,就是一條流水線工做的過程(流水線的工做須要電源,電源就至關於cpu),而一條流水線必須屬於一個車間,一個車間的工做過程是一個進程,車間負責把資源整合到一塊兒,是一個資源單位,而一個車間內至少有一條流水線。ide

  多線程(即多個控制線程)的概念是,在一個進程中存在多個線程,多個線程共享該進程的地址空間,至關於一個車間內有多條流水線,都共用一個車間的資源。例如,北京地鐵與上海地鐵是不一樣的進程,而北京地鐵裏的13號線是一個線程,北京地鐵全部的線路共享北京地鐵全部的資源,好比全部的乘客能夠被全部線路拉。spa

  那麼,爲何要開線程呢?當咱們須要多個程序同時運行,可是還須要數據共享——開進程的話能保證第一點可是數據不能共享,因此要用同一個進程下的多個線程。線程

  因此說,進程只是用來把資源集中到一塊兒(進程只是一個資源單位,或者說資源集合),而線程纔是cpu上的執行單位。光開進程不能工做,須要進程裏開線程才能正常工做,當一個進程開啓時,對應的一個線程會隨着同時開啓個進程能夠開啓多個線程————一個進程內的多個線程是共享數據的開進程的開銷遠遠比開進程的開銷大,由於開進程得申請空間,開線程是基於開好的空間進行的3d

  2、開啓線程的兩種方式code

  2.1 利用threading模塊下的Thread類:對象

# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-
from threading import Thread
import time
import os

def work(name):
    print('%s is running...id:%s'%(name,os.getpid()))
    time.sleep(1)
    print('%s is done...'%os.getpid())


if __name__ == '__main__':
    w = Thread(target=work,args=('whw',))
    #開啓線程開始start方法
    w.start()
    #主進程開啓是默認開啓了主線程,進程要想執行必需要有一個線程
    #如今有一個進程兩個線程
    #執行角度看這是主線程,資源角度講是主進程
    print('主線程~')
View Code

  2.2 利用類的繼承blog

# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-
from threading import Thread
import time
import os

class MYThread(Thread):
    def __init__(self,name):
        super().__init__()
        self.name = name

    def run(self):
        print('%s is running...id:%s' % (self.name,os.getpid()))
        time.sleep(1)
        print('%s is done...'% os.getpid())


if __name__ == '__main__':
    w = MYThread('whw')
    #start
    w.start()
    print('主線程')
View Code

  3、線程與進程的區別:繼承

  3.1 首先,從開銷的角度來說,開進程的開銷要遠遠大於開線程的開銷,由於開進程涉及到空間的建立,而開啓線程僅僅是在既有的空間的基礎上進行的;其次,同一個進程的各個線程之間是共享資源的,而不一樣的進程之間的資源是不共享的。進程

  3.2 咱們如今驗證一下進程與線程的資源共享問題:

  3.2.1 對於多線程來講:,咱們全局定義的n=100,而通過子線程t1的處理,n的值無論是在主線程仍是子線程都變成了0:

# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-

from threading import Thread
import time
import os

n = 100

#方法
def work(name):
    print('%s is running...id:%s'%(name,os.getpid()))
    global n
    n = 0
    time.sleep(2)
    print('%s is done...'%os.getpid())
    print('%s 內n的值爲:%s'%(os.getpid(),n))


if __name__ == '__main__':
    t1 = Thread(target=work,args=('子線程1',))
    t1.start()
    t1.join()

    print(''.center(10,'*'))
    print('主的n:',n)

  線程程序的運行結果:

  3.2.2 對於多進程來講,多個進程之間是不共享資源的:

# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-

from multiprocessing import Process
import time
import os

n = 100

#方法
def work(name):
    print('%s is running...id:%s'%(name,os.getpid()))
    global n
    n = 0
    time.sleep(2)
    print('%s is done...'%os.getpid())
    print('%s 內n的值爲:%s'%(os.getpid(),n))


if __name__ == '__main__':
    p1 = Process(target=work,args=('子進程1',))
    p1.start()
    p1.join()

    print(''.center(10,'*'))
    print('主的n:',n)

  運行結果以下:

  4、Thread對象的其餘屬性及方法:

  Thread對象支持下列需求的方法:

  4.1 找到當前線程的名字與id:

  找到當前線程的名字須要引入current_thread類,用到getName方法:

print(current_thread().getName())

  而找id還能夠利用os模塊小的getpid方法:

print(os.getpid())

  4.2 查看當前存活的線程的名字與數量(注意須要在threading模塊導入相應的類):

# 查看當前存活的線程
print(active_count())

#查看當前存活的具體的線程
print(enumerate())

  4.3 查看線程是否存活:

#造線程對象的時候能夠用name=寫名字
t = Thread(target=work,name='whw1')
t.start()
#查看線程是否存活
print(t.is_alive())

  4.4 設置線程名字

#造線程對象的時候能夠用name=寫名字
t = Thread(target=work,name='whw1')
t.start()
#設置線程的名字
t.setName('兒子線程1')
#設置主線程的名字
current_thread().setName('主線程')

  4.5 固然,還有join方法,等子線程執行完畢再執行主線程

 #造線程對象的時候能夠用name=寫名字
t = Thread(target=work,name='whw1')
t.start()
#等子線程執行完再執行主線程
t.join()
#找到主線程的名字--默認MainThread
print(''.center(10,'*'),current_thread().getName())

  具體的完整代碼以及執行效果以下:

# -*- coding: utf-8  -*-
# -*- Author: WangHW -*-

from threading import Thread,current_thread,active_count,enumerate
import os
import time

def work():
    #找到當前線程的名字與id
    print('%s is running...id:%s:'%(current_thread().getName(),os.getpid()))
    time.sleep(2)
    print('%s is done...'%current_thread().getName())


if __name__ == '__main__':
    #造線程對象的時候能夠用name=寫名字
    t = Thread(target=work,name='whw1')
    t.start()
    # 查看當前存活的線程
    print('當前存活線程個數:',active_count())
    #查看當前存活的具體的線程
    print('當前存活線程的具體信息:',enumerate())
    #查看線程是否存活
    print('子線程是否存活?',t.is_alive())
    #設置線程的名字
    t.setName('兒子線程1')

    #等子線程執行完再執行主線程
    t.join()

    # 查看子線程是否存活
    print('子線程是否存活?',t.is_alive())
    #查看當前存活的線程
    print('當前存活線程個數:',active_count())
    # 查看當前存活的線程
    print('當前存活線程的具體信息:',enumerate())
    #設置主線程的名字
    current_thread().setName('主線程')
    #找到主線程的名字--默認MainThread
    print(''.center(10,'*'),current_thread().getName())
Thread對象的方法

  執行效果:

相關文章
相關標籤/搜索