博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程的理论
阅读量:5162 次
发布时间:2019-06-13

本文共 6659 字,大约阅读时间需要 22 分钟。

线程的理论知识

1.什么是线程

​ 一条流水线的工作流程

之前描述的进程 : 在内存中开启一个进程空间,然后将主进程的所有资源数据复制一份,然后调用 CPU 执行这些代码

之前描述的进程不够具体,具体的应该是这样: 在内存中开启一个进程空间,然后将主进程的所有资源数据复制一份,然后调用线程去执行这些代码

进程是资源单位,线程是执行单位(线程是 CPU 最小的执行单位,进程是由线程执行的)

以后你描述一个开启一个进程 :在内存中开启一个进程空间,然后将主进程的所有资源数据复制一份,然后调用线程去执行这些代码

2.线程 VS 进程

  1. 开启进程的开销非常大,比开启线程的开销大很多
  2. 开启线程的速度非常快,要大几十甚至几百倍
  3. 线程线程之间可以共享数据,进程进程之间必须借助队列等方法实现通信

3.线程的应用

并发 : 一个 CPU 看起来像是执行多个任务

单个进程开启三个进程

开启三个进程并发的执行任务

文本编辑器

  1. 输入文字
  2. 在屏幕上显示
  3. 保存在磁盘中

开启多线程就非常好了 就非常好了 因为你要是打开三个窗口 ,不方便

数据共享,开销小,速度快

4.开启线程的两种方式

第一版

from threading import Threadimport timedef task(name):    print(f"{name} is running")    time.sleep(1)    print(f"{name} is gone")if __name__ == '__main__':    t1 = Thread(target = task,args=("海狗",))    t1.start()    print("====主线程")#  执行的速度非常快

第二版

没传参数的情况

from threading import Threadimport timeclass MyThread(Thread):    def run(self):        print(f"{self.name} is running")        time.sleep(1)        print(f"{self.name} is gone")if __name__ == '__main__':    t1 = MyThread ()    t1.start()    print("====主线程")    '''Thread-1 is running====主线程Thread-1 is gone    类似于进程中不传 self.name 输出的结果是 process - 1'''

传参数的情况

from threading import Threadimport timeclass MyThread(Thread):    def __init__(self,name,l1,s1):        super().__init__()        self.name = name        self.l1 = l1        self.s1 = s1    def run(self):        print(f"{self.name} is running")        time.sleep(1)        print(f"{self.name} is gone")if __name__ == '__main__':    t1 = MyThread ('魏无羡',[1,2,3],"180")    t1.start()    print("====主线程")'''魏无羡 is running====主线程魏无羡 is gone'''

5.线程进程 pid

主线程和子线程没有地位之分,这就引出了一个问题?

一个进程究竟谁在干活?

一个主线程在干活,当干完活了,你得等待其他线程干完活之后,才能结束本线程.

一个进程下的主线程和主进程共用一个 pid 可以这样理解,他们在一个空间里嘛

from threading import Threadimport osdef task():    print(os.getpid())if __name__ == '__main__':    t1 = Thread(target = task)    t2 = Thread(target = task)    t1.start()    t2.start()    print(f"主线程{os.getpid()}")'''5999859998主线程59998   不变不变

6.同一个进程,线程是共享数据的

  1. 进程:子进程和主进程是隔离的
  2. 线程:共享
  3. 同一进程的资源数据对于这个进程的多个线程来说是共享的
from threading import Threadimport osx = 3def task():    global x    x = 100if __name__ == '__main__':    t1 = Thread(target = task)    t2 = Thread(target = task)    t1.start()    t2.start()    print(f"主线程:{x}")#  主线程:100     你看改变了  不是

7.线程的其他方法

几个方法全部都在里了哦

from threading import Threadfrom threading import currentThreadfrom threading import enumeratefrom threading import activeCountimport osimport timex = 3def task():    time.sleep(1)    print(666)if __name__ == '__main__':    t1 = Thread(target = task,name = '线程 1')    t2 = Thread(target = task,name = '线程 2')    #  设置线程名    t1.start()    t2.start()    time.sleep(1)    print(t1.isAlive())    #  判断线程是否活着  返回 True or False    # print(t1.getName())  #  获取线程名    # t1.setName('子线程-1')   #  修改线程名    # print(t1.name)         #  获取线程名   重要****************************************    # print(currentThread()) # 获取当前线程的对象,并且是主线程哦    # print(enumerate())   # 返回一个列表,包含所有的线程对象    # print(activeCount()) #  返回活着的线程数   重要***************************************    # print(f"===主线程{os.getpid()}")

8.join 与守护线程

并发的情况

from threading import Threadimport timedef task(name):    print(f"{name} is running")    time.sleep(1)    print(f"{name} is gone")if __name__ == '__main__':    start_time = time.time()    t1 = Thread(target = task,args = ('海狗',))    t2 = Thread(target = task,args = ('海狗1',))    t3 = Thread(target = task,args = ('海狗2',))    t1.start()    t2.start()    t3.start()    t1.join()    t2.join()    t3.join()    print(f"主线程{time.time() - start_time}")'''海狗 is running海狗1 is running海狗2 is running海狗 is gone海狗1 is gone海狗2 is gone主线程1.0073320865631104

串行的情况 : 一个一个的执行

from threading import Threadimport timedef task(name):    print(f"{name} is running")    time.sleep(1)    print(f"{name} is gone")if __name__ == '__main__':    start_time = time.time()    t1 = Thread(target = task,args = ('海狗',))    t2 = Thread(target = task,args = ('海狗1',))    t3 = Thread(target = task,args = ('海狗2',))    t1.start()    t1.join()    t2.start()    t2.join()    t3.start()    t3.join()    print(f"主线程{time.time() - start_time}")'''海狗 is running海狗 is gone海狗1 is running海狗1 is gone海狗2 is running海狗2 is gone主线程3.0137791633605957'''

回忆一下守护进程

from multiprocessing import Processimport timedef foo():    print(123)    time.sleep(1)    print('end123') #  随着主进程的结束这个就不执行了def bar():    print(456)    time.sleep(1)    print('end456')if __name__ == '__main__':    p1 = Process(target = foo)    p2 = Process(target = bar)    p1.daemon = True    p1.start()    p2.start()    print('===主')'''===主123456end456'''

我们看一下守护线程,结果很秀

简单版本的

from  threading import Threadimport timedef sayhi(name):    print('你滚')    time.sleep(2)    print("%s say hello"%name)if __name__ == '__main__':    t = Thread(target = sayhi,args = ('大黄',))    t.setDaemon(True)   #  必须在t.start()之前    # t.daemon = True   这个也是    t.start()    print("主线程")'''你滚主线程'''

下面两版作对比

from threading import Threadimport timedef foo():    print(123)    time.sleep(1)    print('end123')def bar():    print(456)    time.sleep(1)    print('end456')t1 = Thread(target = foo)t2 = Thread(target = bar)t1.daemon = Truet1.start()t2.start()print("main------")'''123456main------end123end456'''注意end123 输出来了

将上面时间改一下,结果就变了

from threading import Threadimport timedef foo():    print(123)    time.sleep(3)    print('end123')def bar():    print(456)    time.sleep(1)    print('end456')t1 = Thread(target = foo)t2 = Thread(target = bar)t1.daemon = Truet1.start()t2.start()print("main------")'''123456main------end456'''

总结 : 守护线程等待非守护线程以及主线程结束后结束

PS : 就是主线程等其他进程,守护进程等待主线程

需要重点理解的,还没加锁的情况

from threading import Threadimport timeimport randomx = 100def task():    time.sleep(random.randint(1,2))    global x    temp = x    time.sleep(random.randint(1, 2))    temp = temp - 1    x = tempif __name__ == '__main__':    l1 = []    for i in range(100):        t = Thread(target = task)        l1.append(t)        t.start()        #t.join()  这里的结果是串行,自己测试的    for i in l1:        i.join()           '''        放在这里的效果相当于并发   就像是之前的那个代码,1  2  3           join放在下面  一样  但 要是紧跟着,那就是串行,这里还是并发        运行速度非常快,一窝蜂全部拿到  x = 100  不是其他人不执行,而是        结果都是一样的 99        '''        print(f"主线程:{x}")

多个任务公抢一个资源时,要让其串行,所以选择加锁

from threading import Threadfrom threading import Lockimport timeimport randomx = 100def task(lock):    lock.acquire()    global x    temp = x    time.sleep(0.01)    temp = temp - 1  #  这样写的原因是这一步执行太快,所以写开    x = temp    lock.release()if __name__ == '__main__':    mutex = Lock()    l1 = []    for i in range(100):        t = Thread(target = task,args = (mutex,))        l1.append(t)        t.start()    time.sleep(3)    print(f'主进程{x}')'''主进程0  这是最终的结果'''

转载于:https://www.cnblogs.com/hualibokeyuan/p/11395739.html

你可能感兴趣的文章
Confluence 6 升级以后
查看>>
用JS实现版面拖拽效果
查看>>
二丶CSS
查看>>
《avascript 高级程序设计(第三版)》 ---第二章 在HTML中使用Javascript
查看>>
JS一些概念知识及参考链接
查看>>
TCP/IP协议原理与应用笔记24:网际协议(IP)之 IP协议的简介
查看>>
SAP HANA开发中常见问题- 基于SAP HANA平台的多团队产品研发
查看>>
游戏中的心理学(一):认知失调有前提条件
查看>>
WHAT I READ FOR DEEP-LEARNING
查看>>
【Ruby】Ruby在Windows上的安装
查看>>
Objective C 总结(十一):KVC
查看>>
BZOJ 3747 洛谷 3582 [POI2015]Kinoman
查看>>
vue实战(7):完整开发登录页面(一)
查看>>
[转载]mysql的left,right,substr,instr截取字符串,截取
查看>>
Visual Studio自定义模板(二)
查看>>
【Mood-20】滴滤咖啡做法 IT工程师加班必备 更健康的coffee 项目经理加班密鉴
查看>>
读《构建之法-软件工程》第四章有感
查看>>
使用 Printf via SWO/SWV 输出调试信息
查看>>
.net 分布式架构之分布式锁实现(转)
查看>>
吴恩达机器学习笔记 —— 3 线性回归回顾
查看>>