第一阶段:Python开发基础 day38 多线程的创建和一些常用方法

昨日回顾

'''
### 抢票小案例优化,基于磁盘做进程通讯
# start() 紧跟着join 变成了整体串行,保证了数据的安全,降低了效率.
# 进程锁 from multiprocessing import Lock   用进程锁的不同是只是针对处理数据的代码变成串行.
    lock= Lock()
    传给子进程
    def  在子进程里面(lock):
        代码一
        代码二

        lock.acquire()
        处理数据
        lock.release()

### 进程通讯 ipc机制
# Queue 队列模块 实现
# 管道+锁
# 管道:底层基于共享内存
# from multiprocessing import Queue
# q = Queue(maxsize)
q.put(obj) # 如果队列满了,会阻塞在这里.
q.get()# 如果队列空了,会阻塞在这里.

了解
# block = False 不等了满了或空了 直接报错
# block = True timeout = 等待的超时时间.

### 生产者消费者模型
# 吃包子案例
# 生产者 --> 队列(盆) --> 消费者
# 生产者只需要不停的生产,达到了自己的最大效率,
  消费者也只需要不听的消费,也达到了自己的最大效率.
  生产者消费者模型,大大提高了生产者的生产效率,也大大提高了消费者的消费效率.

# Joinablequeue
# 底层维护了以计数器
# q.put +1       q.task_done -1
# q.join() 当计数器不为0的时候阻塞,当计数器为0的时候不阻塞

# 今日内容

#  线程内容(*****)
#  线程的两种开启方式(*****)
#  线程vs进程 速度 内存是否共享(*****)
#  线程的join方法(*****)
#  单核下同一个进程的线程如何切换(***)
#  线程的其他方法(*)
#  守护线程(*)
'''

一、线程内容

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

操作系统 ===> 工厂
进程 ===> 车间
线程 ===> 流水线
cpu  ===> 电源

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

右键运行:
申请内存空间,先把解释器丢进去并且把代码丢进去(进程做的),运行代码(线程).

进程和线程的区别:

过程描述的区别
线程==》单指代码的执行过程
进程==》资源的申请与销毁的过程


进程内存空间彼此隔离
同一个进程下的线程共享资源.

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

'''

二、线程开启的两种方式(一)

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('主')

三、线程开启的两种方式(二)

from threading import Thread
import time
# 进程等待所有线程结束才会结束

class Myt(Thread):
    def run(self):
        print('子线程 start')
        time.sleep(5)
        print('子线程 end')

t = Myt()
t.start()
print('主线程')

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

from threading import Thread
from multiprocessing import Process
import time

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


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

'''
开启子线程的打印效果:

子线程 is running
主
子线程 is end

开启子进程打印效果:

主
子进程 is running
子进程 is end


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

'''

五、子线程共享资源

from threading  import Thread
import time,os

x = 100
def task():
    global x
    x = 50
    print(os.getpid()) # 5204


if __name__ == '__main__':

    t = Thread(target=task)
    t.start()
    time.sleep(2)
    print(x) # 50
    print(os.getpid()) # 5204

六、线程的join方法

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() # 111s
t2.join() #
t3.join()
end = time.time() # 3.0039877891540527
# 思考一下 在单核的情况下 多个线程是如何利用cpu的
print(end-start)


# print('主线程')

七、了解进程的join

from multiprocessing import Process
from threading import Thread
import time
def task():
    print('进程 开启')
    time.sleep(10)
    print('进程 结束')
def task2():
    print('子线程 开启')
    time.sleep(2)
    print('子线程 结束')

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

八、线程其他相关用法

from multiprocessing import Process
from threading import Thread
import time
def task():
    print('进程 开启')
    time.sleep(10)
    print('进程 结束')
def task2():
    print('子线程 开启')
    time.sleep(2)
    print('子线程 结束')

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

九、线程其他相关用法

from threading import Thread,currentThread,enumerate,activeCount
# import threading
import time
# threading.current_thread()
# threading.current_thread()

def task():
    print('子线程 start')
    time.sleep(2)
    print('子线程 end')
    print(enumerate())
    # print(currentThread(),'子线程')
if __name__ == '__main__':
   t1 = Thread(target=task)
   t2 = Thread(target=task)
   t1.start()
   t2.start()



   # print(t1.is_alive()) # True
   # print(t1.getName()) # Thread-1
   # print(t2.getName()) # Thread-2
   # t1.setName('班长')
   # print(t1.getName())
   # print(currentThread().name)
   # print(enumerate()) # [<_MainThread(MainThread, started 1856)>, <Thread(Thread-1, started 6948)>, <Thread(Thread-2, started 3128)>]
   # print(activeCount()) # 3
   # print(len(enumerate())) # 3

十、守护线程

# 守护线程 守护的是进程的运行周期
from threading import Thread,enumerate,currentThread
import time

def task():
    print('守护线程开始')
    print(currentThread())
    time.sleep(20)
    # print('守护线程结束')

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('主')
posted @ 2019-09-17 17:25  foreversun92  阅读(201)  评论(0编辑  收藏  举报