多线程

多线程

在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程

线程顾名思义,就是一条流水线工作的过程(流水线的工作需要电源,电源就相当于cpu),而一条流水线必须属于一个车间,一个车间的工作过程是一个进程,车间负责把资源整合到一起,是一个资源单位,而一个车间内至少有一条流水线。

所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位。

多线程(即多个控制线程)的概念是,在一个进程中存在多个线程,多个线程共享该进程的地址空间,相当于一个车间内有多条流水线,都共用一个车间的资源。例如,北京地铁与上海地铁是不同的进程,而北京地铁里的13号线是一个线程,北京地铁所有的线路共享北京地铁所有的资源,比如所有的乘客可以被所有线路拉。

开启线程的两种方式

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

#方法一:
# from threading import Thread
# import time

# def task(name):
#     print('%s is runing'%name)
#     time.sleep(3)
#     print('%s is done'%name)
#
# if __name__ == '__main__':
#     t = Thread(target=task,kwargs={'name':'线程'})  # 方法调用2
#     t1 = Thread(target=task,kwargs={'name':'线程1'})  # 方法调用2
#     t.start()
#     t1.start()
#     print('A')

# 方法二:
from threading import Thread
import time
class My_process(Thread): # 继承Process类
    def __init__(self,name):
        super().__init__() # 继承init方法
        self.name = name

    def run(self):  # 固定写法
        print('%s is runing'%self.name)
        time.sleep(3)
        print('%s id done'%self.name)

if __name__ == '__main__':
    t = My_process('线程')
    t.start()
    print('b')

线程与进程的区别

  • 同一个进程内的多个线程共享该进程内的地址资源
  • 创建线程的开销要远小于创建进程的开销(创建一个进程,就是创建一个车间,涉及到申请空间,而且在该空间内建至少一条流水线,但创建线程,就只是在一个车间内造一条流水线,无需申请空间,所以创建开销小)

开进程的开销远大于开线程

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# 线程的开启速度比进程要快
from threading import Thread
from  multiprocessing import Process
import time
def work(name):
    print('%s is running'%name)
    time.sleep(2)
    print('%s is done'%name)

if __name__ == '__main__':
    t = Thread(target=work,args=('ab',))
    t.start()
    print('线程')
    p = Process(target=work,args=('abc',))
    p.start()
    print('主进程')
'''
ab is running
线程
主进程
abc is running
ab is done
abc is done
'''

同一进程内的多个线程共享该进程的地址空间

from threading import Thread
from  multiprocessing import Process
import time
n = 100
def num():
    global n
    n = 0
if __name__ == '__main__':
    t = Thread(target=num)
    t.start()
    t.join()
    print('线程',n) # 同一进程内开启的多个线程是共享该进程地址空间的
    # p = Process(target=num)
    # p.start()
    # p.join()
    # print('进程',n)  # 进程之间,地址空间是隔离的
'''
线程 0
进程 100
'''

瞅一眼PID

from threading import Thread
from multiprocessing import Process
from multiprocessing import current_process
import os
#开多个进程,每个进程都有不同的pid
# def task():
#     print('子进程的PID:%s,主进程PID:%s'%(os.getpid(),os.getppid()))
#
# if __name__ == '__main__':
#     p = Process(target=task)
#     p.start()
#     print('主进程的PID:%s'%os.getpid())
'''
主进程的PID:32228
子进程的PID:18680,主进程PID:32228
'''
#在主进程下开启多个线程,每个线程都跟主进程的pid一样
def task1():
    print('主线程的PID:%s'%os.getpid())

if __name__ == '__main__':
    t = Thread(target=task1,)
    t.start()
    print('主线程的pid:%s'%os.getpid())
'''
主线程的PID:24260
主线程的pid:24260
'''

Thread对象的其它属性方法

介绍

Thread实例对象的方法
  # isAlive(): 返回线程是否活动的。
  # getName(): 返回线程名。
  # setName(): 设置线程名。

threading模块提供的一些方法:
  # threading.currentThread(): 返回当前的线程变量。
  # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

例子:

from threading import Thread
import threading
import  time

def work():
    time.sleep(3)    print(threading.current_thread().name)

if __name__ == '__main__':
    t = Thread(target=work)
    t.start()
  print(threading.current_thread().getName())
    print(threading.current_thread())# 主线程
    print(threading.enumerate()) # 连同主线程有两个正
    print(threading.active_count()) # 返回线程的数量
    print('主线程')
'''
MainThread
<_MainThread(MainThread, started 29804)>
[<_MainThread(MainThread, started 29804)>, <Thread(Thread-1, started 23704)>]
2
主线程
Thread-1
'''

主线程等待子线程结束

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from threading import Thread
import threading
import  time

def work():
    time.sleep(3)
    print(threading.current_thread().name)

if __name__ == '__main__':
    t = Thread(target=work,name='test')
    t.start()
    t.join()
    print(t.is_alive())
    print('主线程')
'''
test
False
主线程
'''
原文地址:https://www.cnblogs.com/yjiu1990/p/9263252.html