前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python之线程相关操作

python之线程相关操作

作者头像
py3study
发布2020-01-20 14:13:29
3140
发布2020-01-20 14:13:29
举报
文章被收录于专栏:python3python3

1.线程: 一个进程可以有多个线程,共享一个进程的资源;

2.进程线程的区别:

   进程是资源分配的最小单位,线程是程序执行的最小单位

3.python中线程模块threading, 提供的类: Thread, Lock, Rlock, Semaphore, Event, 等等

4.线程的创建方式

代码语言:javascript
复制
# 第一种
# from threading import Thread
# def f1(s):
#     print('我是%s' % s)
# def f2(s):
#     print('我是%s' % s)
# 
# if __name__ == '__main__':
#     t = Thread(target=f1, args=(1,))
#     t1 = Thread(target=f1, args=(2,))
#     t.start()
#     t1.start()
#     print('我是主线程')

# 第二种
from threading import Thread

class MyThread(Thread):
    def __init__(self, name):
        super().__init__()
        self.name = name
    def run(self):
        print('%s今天还是不能皮' % self.name)
if __name__ == '__main__':
    t = MyThread('Jerry')
    t.start()
    print('主线程')

6.查看线程的进程id(同进程查看方式一样)

代码语言:javascript
复制
import os
from threading import Thread
def f1(n):
    print('1号', os.getpid())
    print('%s号线程任务' % n)
def f2(n):
    print('2号', os.getpid())
    print('%s号线程任务' % n)
if __name__ == '__main__':
    t1 = Thread(target=f1, args=(1,))
    t2 = Thread(target=f2, args=(2,))
    t1.start()
    t2.start()
    print('主线程', os.getpid())
    print('主线程')

7. 在进程之间数据是空间隔离的, 而在线程中是数据共享的

代码语言:javascript
复制
import time
from threading import Thread

#  通过对全局变量的修改来验证线程之间是数据共享的, 共享同一进程中的数据
num = 100
def f1():
    time.sleep(3)
    global  num
    num = 3
    print('子线程的num', num)

if __name__ == '__main__':
    t = Thread(target=f1)
    t.start()
    t.join() # 等待子线程运行结束才继续向下执行
    print('主线程的num', num)

8.多进程和多线程的效率对比

对于io密集型的, 多线程的时间较快

代码语言:javascript
复制
def f1():
    time.sleep(1)  #io密集型
    
if __name__ == '__main__':
    # 查看一下20个线程执行20个任务的执行时间
    t_s_time = time.time()
    t_list = []
    for i in range(5):
        t = Thread(target=f1,)
        t.start()
        t_list.append(t)
    [tt.join() for tt in t_list]
    t_e_time = time.time()
    t_dif_time = t_e_time - t_s_time
    # 查看一下20个进程执行同样的任务的执行时间
    p_s_time = time.time()
    p_list = []
    for i in range(5):
        p = Process(target=f1,)
        p.start()
        p_list.append(p)
    [pp.join() for pp in p_list]
    p_e_time = time.time()
    p_dif_time = p_e_time - p_s_time
    print('多线程的执行时间:', t_dif_time)
    print('多jincheng的执行时间:', p_dif_time)

计算型:

代码语言:javascript
复制
import time
from threading import Thread
from multiprocessing import Process

def f1():
    # 计算型:
    n = 10
    for i in range(10000000):
        n = n + i
if __name__ == '__main__':
    # 查看一下20个线程执行20个任务的执行时间
    t_s_time = time.time()
    t_list = []
    for i in range(5):
        t = Thread(target=f1,)
        t.start()
        t_list.append(t)
    [tt.join() for tt in t_list]
    t_e_time = time.time()
    t_dif_time = t_e_time - t_s_time
    # 查看一下20个进程执行同样的任务的执行时间
    p_s_time = time.time()
    p_list = []
    for i in range(5):
        p = Process(target=f1,)
        p.start()
        p_list.append(p)
    [pp.join() for pp in p_list]
    p_e_time = time.time()
    p_dif_time = p_e_time - p_s_time
    print('多线程的执行时间:', t_dif_time)
    print('多jincheng的执行时间:', p_dif_time)

 9.锁,同步,互斥锁 为了保护多线成中数据的完整性和线程间状态的同步.(同进程的锁一样)

 在线程锁中, 会产生死锁现象. 同时抢锁

代码语言:javascript
复制
import time
from threading import Thread, Lock, RLock
def f1(locA, locB):
    # print('xxxx')
    # time.sleep(0.1)
    locA.acquire()
    print('f1>>1号抢到了A锁')

    time.sleep(1)
    locB.acquire()
    print('f1>>1号抢到了B锁')
    locB.release()

    locA.release()
def f2(locA, locB):
    print('22222')
    time.sleep(0.1)
    locB.acquire()
    print('f2>>2号抢到了B锁')
    locA.acquire()
    time.sleep(1)
    print('f2>>2号抢到了A锁')
    locA.release()
    locB.release()
if __name__ == '__main__':
    locA = Lock()
    locB = Lock()
    t1 = Thread(target=f1, args=(locA, locB))
    t2 = Thread(target=f2, args=(locA, locB))
    t1.start()
    t2.start()

  递归锁解决了 死锁现象

代码语言:javascript
复制
import time
from threading import Thread, Lock, RLock

def f1(locA, locB):
    print('xxxxx')
    time.sleep(0.1)
    locA.acquire()
    print('f1>>>1号抢到了A锁')
    time.sleep(1)
    locB.acquire()
    print('f1>>>2号抢到了B锁')
    locB.release()
    locA.release()
def f2(locA, locB):
    print('22222')
    time.sleep(0.1)
    locB.acquire()
    print('f2>>>1号抢到了A锁')
    time.sleep(1)
    locA.acquire()
    print('f2>>>2号抢到了B锁')
    locA.release()
    locB.release()
if __name__ == '__main__':
    locA = locB = RLock()
    t1 = Thread(target=f1, args=(locA, locB))
    t2 = Thread(target=f2, args=(locB, locA))
    t1.start()
    t2.start()

10.多线程的程序不结束 和 多进程的程序不结束的区别

代码语言:javascript
复制
守护进程:主进程代码执行运行结束,守护进程随之结束
守护线程:守护线程会等待所有非守护线程运行结束才结束
代码语言:javascript
复制
import time
from threading import Thread
from multiprocessing import Process


# 守护进程:主进程代码执行运行结束,守护进程随之结束
# 守护线程:守护线程会等待所有非守护线程运行结束才结束
def f1():
    time.sleep(2)
    print('一号线程')

def f2():
    time.sleep(3)
    print('二号线程')
def f3():
    time.sleep(2)
    print('一号进程')

def f4():
    time.sleep(3)
    print('二号进程')
if __name__ == '__main__':
    # t1 = Thread(target=f1,)
    # t2 = Thread(target=f2,)
    # # t1.daemon = True  #  等非守护线程结束,守护线程才会结束 结果:  主线程结束  一号线程  二号线程
    # t2.daemon = True # 结果: 主线程结束      一号线程
    # t1.start()
    # t2.start()
    # print('主线程结束')
    p1 = Process(target=f3,)
    p2 = Process(target=f4,)
    # p1.daemon = True # 结果: 主进程   二号线程
    p2.daemon= True # 结果: 主进程   一号线程
    p1.start()
    p2.start()
    print('主进程')

11. GIL锁 :  cpython解释器上的一把互斥锁, Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核

Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-05-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档