线程基础和用法

一、线程

  1. 初识线程
    在传统操作系统种,每个进程有一个地址空间,而且默认就有一个控制线程,cpu真正的执行单位是线程。
    在工厂中,每一个车间都有房子,而且每个车间默认就有一个流水线。

  2. 做一个比较

    ​ 相当于
    操作系统------->工厂
    进程------->车间
    线程------->流水线
    cpu------->电源

  3. 线程:cpu最小的执行单位
    进程:资源集合/资源单位
    线程运行 ------->代码运行
    进程运行------->各种资源 + 线程

  4. 右键运行会发生的事情:申请内存空间,先将解释器代码丢进去并且把python代码丢进去(进程做的)(内存运行的时候不识别python文件代码,只有解释器才能识别python文件代码,所有先把解释器放入内存),运行代码(线程)

  5. 进程和线程的区别:
    过程描述的区别
    线程------->单指代码的执行过程
    进程------->资源的申请与销毁的过程

  6. 进程内存空间彼此隔离(内存共享or隔离

    多个进程内存空间彼此隔离。

    同一进程下的多个线程共享该进程内的数据。同一个进程下的线程共享资源

  7. 进程和线程的创造速度
    进程需要申请资源开辟空间------->慢
    只是告诉操作系统一个执行方案------->快

    扫描二维码关注公众号,回复: 7303713 查看本文章
  8. 1 进程的启动和销毁(空间开始和释放)

    只要一说一个进程启动了,那你知道了一个事情,是关于这个程序的一块空间造好了。

    只要一说进程销毁了,那你也知道了一个事情,是关于这个程序的空间释放了。

    2 线程的启动和销毁(进程里的一段代码运行起来了,进程里的一段代码运行结束)

  9. 进程之间是竞争关系,线程之间是协作关系?(了解)

    车间直接是竞争/抢电源的关系,竞争(不同的进程直接是竞争关系,是不同的程序员写的程序运行的,迅雷抢占其他进程的网速,360把其他进程当做病毒干死)
    一个车间的不同流水线式协同工作的关系(同一个进程的线程之间是合作关系,是同一个程序写的程序内开启动,迅雷内的线程是合作关系,不会自己干自己)

二、开启线程的俩种方式

由于线程开启不会出现一直循环调用开启的情况和进程是不同的,所以不需要用main来隔绝,但可以使用。

2.1方式1

from threading import Thread
import time
def task():
    print('线程 start')
    time.sleep(2)
    print('线程end')
if __name__ == '__main__':
    t = Thread(target=task)
    t.start()
    print('主进程')
################
线程 start
主进程
线程end

2.2方式2

from threading import Thread
import time
class Myt(Thread):
    def run(self):
        print('子进程 start')
        time.sleep(2)
        print('子进程 end')
t = Myt()
t.start()
print('主')
#######################
子进程 start
主
子进程 end

三、子进程vs子线程创建速度

from threading import Thread
from multiprocessing import Process
import time


def task(name):
    print(f'{name} is runing')
    time.sleep(2)
    print(f'{name} is endding')


if __name__ == '__main__':
    t= Thread(target=task,args=('子线程',))
    p = Process(target=task,args=('子进程',))
    t.start()
    p.start()
    print('主')
##########################
子线程 is runing
主
子进程 is runing
子线程 is endding
子进程 is endding
from threading import Thread
from multiprocessing import Process
import time


def task(name):
    print(f'{name} is runing')
    time.sleep(2)
    print(f'{name} is endding')


if __name__ == '__main__':
    t= Thread(target=task,args=('子线程',))
    # p = Process(target=task,args=('子进程',))
    t.start()
    # p.start()
    print('主')
#######################
子线程 is runing
主
子线程 is endding
from threading import Thread
from multiprocessing import Process
import time


def task(name):
    print(f'{name} is runing')
    time.sleep(2)
    print(f'{name} is endding')


if __name__ == '__main__':
    # t= Thread(target=task,args=('子线程',))
    p = Process(target=task,args=('子进程',))
    # t.start()
    p.start()
    print('主')
##################
主
子进程 is runing
子进程 is endding

四、子线程共享资源

from threading import Thread
import time,os
x = 100
def task():
    global x
    x = 50
    print(os.getpid())
if __name__ == '__main__':
    t = Thread(target=task)
    t.start()
    time.sleep(2)
    print(x)
    print(os.getpid())#处于一个进程,所以pid是一样的
###########
16656
50
16656

五、线程的jion方法

5.1方法1


from threading import Thread
import time
def task():
    print('子线程 start')
    time.sleep(2)
    print('子线程 end')
t = Thread(target=task)
t.start()
t.join()#等待子线程运行结束
print('主线程')
################
子线程 start
子线程 end
主线程

思考主线程是否会等子线程运行结束

1 其实是进程在等
貌似是主线程在原地等着,主线程已经运行完。
原来没有子线程的情况下,其实就一个主线程这一条流水线工作完了,这个进程就结束了。
那现在的情况是当前进程有其他的子线程,是进程等待自己所有的子线程运行完。

# 主进程等子进程是因为主进程要给子进程收尸
# 现在看到的等是进程必须等待其内部所有线程都运行完毕才结束。

5.2方法2

from threading import Thread
import time
def task(name,n):
    print(f'{name} start')
    time.sleep(n)
    print(f'{name} end')
t1 = Thread(target=task,args=('线程1',1))
t2 = Thread(target=task,args=('线程2',2))
t3 = Thread(target=task,args=('线程3',3))
start = time.time()
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
end = time.time()
print(end-start)
##########################
线程1 start
线程2 start
线程3 start
线程1 end
线程2 end
线程3 end
3.0029337406158447

5.3了解进程的jion

from multiprocessing import Process
from threading import Thread

import time
def task():
    print('进程 start')
    time.sleep(10)
    print('进程  end')
def task2():
    print('子线程 start')
    time.sleep(3)
    print('子线程 end')
if __name__ == '__main__':
    p = Process(target=task)
    t = Thread(target=task2)
    t.start()
    p.start()
    print('子进程的join开始')
    p.join()#主进程的主线程等待子进程运行结束
    print('主')
##################
子线程 start
子进程的join开始
进程 start
子线程 end
进程  end
主

六、守护线程

# 守护线程首先是一个线程。
    # 守护线程守护到当前进程运行结束。
    # ps:比如有未完成的子进程阶段会守护,比如有未完成的其他子线程也均会守护。
# 守护进程首先是一个进程。
    # 守护进程守护到当前进程的最后一行代码结束。
from threading import Thread,enumerate,currentThread
import time
def task():
    print('守护线程开始')
    print(currentThread())
    time.sleep(10)
    print('守护线程end')
def task2():
    print('子线程 start')
    time.sleep(5)
    print(enumerate())
    print('子线程 end')
if __name__ == '__main__':
    t1 = Thread(target=task)
    t2 = Thread(target=task2)
    t1.daemon = True
    t2.start()
    t1.start()
    print('主')
####################
子线程 start
守护线程开始
<Thread(Thread-1, started daemon 13904)>
主
[<_MainThread(MainThread, stopped 13828)>, <Thread(Thread-2, started 3316)>, <Thread(Thread-1, started daemon 13904)>]
子线程 end

七、线程其他的相关用法

Thread实例对象的方法

  1. isAlive(): 返回线程是否活动的。
  2. getName(): 返回线程名。
  3. setName(): 设置线程名。

threading模块提供的一些方法:

  1. threading.currentThread(): 返回当前的线程变量。
  2. threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  3. threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果
  • isalive()

    from threading import Thread,currentThread,enumerate,activeCount
    import time
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程  end')
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task)
        t1.start()
        t2.start()
    
    
        print(t1.is_alive())#子线程存在,True
    #################
    子线程 start
    子线程 start
    True
    子线程  end
    子线程  end
    
    
  • getname()

    from threading import Thread,currentThread,enumerate,activeCount
    import time
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程  end')
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t1.start()
    
    
        print(t1.getName())
    
    ##########################
    子线程 start
    Thread-1
    子线程  end
    
    
  • setname()

    from threading import Thread,currentThread,enumerate,activeCount
    import time
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程  end')
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t1.start()
    
        t1.setName('线程1')
        print(t1.getName())
    #####################
    子线程 start
    线程1
    子线程  end
    
  • currentTread()

  • enumerate()

    from threading import Thread,currentThread,enumerate,activeCount
    import time
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程  end')
        print(enumerate())
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task)
        t1.start()
        t2.start()
    ###################################
    子线程 start
    子线程 start
    子线程  end
    [<_MainThread(MainThread, stopped 12328)>, <Thread(Thread-1, started 6176)>, <Thread(Thread-2, started 14452)>]
    子线程  end
    [<_MainThread(MainThread, stopped 12328)>, <Thread(Thread-2, started 14452)>]
    
    from threading import Thread,currentThread,enumerate,activeCount
    import time
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程  end')
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task)
        t1.start()
        t2.start()
        print(enumerate())
    ########################
    子线程 start
    子线程 start
    [<_MainThread(MainThread, started 16964)>, <Thread(Thread-1, started 15796)>, <Thread(Thread-2, started 15476)>]
    子线程  end
    子线程  end
    
  • activeCount()与len(enumerate())

    from threading import Thread,currentThread,enumerate,activeCount
    import time
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程  end')
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task)
        t1.start()
        t2.start()
        print(activeCount())
        print(len(enumerate()))
    #################
    子线程 start
    子线程 start
    3
    3
    子线程  end
    子线程  end
    
  • 1

    from threading import Thread,currentThread,enumerate,activeCount
    import time
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程  end')
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task)
        t1.start()
        t2.start()
        print(currentThread())
        print(currentThread().name)
    ##################
    子线程 start
    子线程 start
    <_MainThread(MainThread, started 2696)>
    MainThread
    子线程  end
    子线程  end
    
    

猜你喜欢

转载自www.cnblogs.com/SkyOceanchen/p/11537610.html