zoukankan      html  css  js  c++  java
  • 线程

    一、线程

    1.什么是线程?

    首先我们要知道,进程线程其实都是虚拟单位,都是用来帮助我们形象的描述某种事物

    进程:资源单位

    线程:执行单位

    将内存比喻成工厂

    那么进程就相当于是工厂里面的车间

    而你的线程就相当于是车间里面的流水线

    ps:每个进程都自带一个线程,线程才是真正的执行单位,进程只是在线程运行过程中提供代码运行所需要的资源

    2.为什么要有线程

    开进程

      1.申请内存空间 耗资源

         2.“拷贝代码” 耗资源

    开线程

      一个进程内可以起多个线程,并且线程与线程之间数据是共享的

    PS:开启线程的开销要远小于开启进程的开销

    二、创建进程的两种方式

      方式一:

     1 from threading import Thread
     2 import time
     3 
     4 def task(name):
     5     print('%s is running'%name)
     6     time.sleep(3)
     7     print('%s is over'%name)
     8 
     9 #开线程不需要在__main__代码块中,但是出于习惯,我们可以写在__main__代码块中
    10 t = Thread(target=task,args=('jason',))
    11 t.start() #告诉操作系统开辟一个线程
    12 #小的代码执行完,线程就已经开启了
    13 print('')

      方式二:

     1 from threading import Thread
     2 import time
     3 
     4 class MyThread(Thread):
     5     def __init__(self,name):
     6         super().__init__()
     7         self.name = name
     8 
     9     def run(self):
    10         print('%s is running'%(self.name))
    11         time.sleep(3)
    12         print('%s is over'%(self.name))
    13 
    14 t = MyThread('jason')
    15 t.start()
    16 print('')

    三、线程对象及其他方法

     1 from threading import Thread,current_thread,active_count
     2 import os
     3 import time
     4 
     5 def task(name,i):
     6     print('%s is running'%name)
     7     print('字current_thread:',current_thread().name)
     8     print('',os.getpid())
     9     time.sleep(i)
    10     print('%s is over'%name)
    11 
    12 t = Thread(target=task,args=('jason',1))
    13 t1 = Thread(target=task,args=('tank',2))
    14 t.start()
    15 t1.start()
    16 t1.join() #主线程等待子线程运行完毕
    17 print('当前正在活跃的线程数',active_count())
    18 print('')
    19 print('主current_thread:',current_thread().name)
    20 print('',os.getpid())

    四、守护线程

     1 from threading import Thread,current_thread
     2 import time
     3 
     4 def task(i):
     5     print(current_thread().name)
     6     time.sleep(i)
     7     print('GG')
     8 
     9 t = Thread(target=task,args=(1,))
    10 t.daemon = True
    11 t.start()
    12 print('')

    主线程的结束也就意味着进程的结束

    主线程必须等待其他非守护线程的结束才能结束,原因是:因为子线程在运行时需要使用进程中的资源,而主线程一旦结束了资源也就销毁了

    五、线程间通信

     1 from threading import Thread
     2 
     3 money = 666
     4 
     5 def task():
     6     global money
     7     money = 999
     8 
     9 t = Thread(target=task)
    10 t.start()
    11 t.join()
    12 print(money)
    13 
    14 '''
    15 事实证明线程与线程之间可以进行通信
    16 '''

    六、互斥锁

     1 from threading import Thread,Lock
     2 import time
     3 
     4 n = 100
     5 
     6 def task(mutex):
     7     global n
     8     mutex.acquire()
     9     num = n
    10     time.sleep(0.1)
    11     n = num - 1
    12     mutex.release()
    13 
    14 t_list = []
    15 mutex = Lock()
    16 for i in range(100):
    17     t = Thread(target=task,args=(mutex,))
    18     t.start()
    19     t.join()
    20 print(n)

    七、小例题及分析

     1 from threading import Thread
     2 from multiprocessing import Process
     3 import time
     4 def foo():
     5     print(123)
     6     time.sleep(1)
     7     print("end123")
     8 
     9 def bar():
    10     print(456)
    11     time.sleep(3)
    12     print("end456")
    13 
    14 if __name__ == '__main__':
    15     t1=Thread(target=foo)
    16     t2=Thread(target=bar)
    17     t1.daemon=True
    18     t1.start()
    19     t2.start()
    20     print("main-------")

    结果为:

    '''
        123
        456
        main-------
        end123
        end456
    '''

    分析:

    首先创建两个线程对象,将t1设置为守护线程,意味着主进程执行完毕后,就会一起终止t1,然后,执行t1线程,紧接着执行t2线程,所以首先打印:123,456。然后根据主线程代码打印了:main-----。此时t1暂停一秒后执行了打印:end123。t1运行结束,但是此时t2并未运行结束,所以主线程会继续等待t2线程运行结束再结束执行。3秒过后t2执行打印:end456。t2也运行结束,主线程随之终止。

  • 相关阅读:
    Leetcode Plus One
    Leetcode Swap Nodes in Pairs
    Leetcode Remove Nth Node From End of List
    leetcode Remove Duplicates from Sorted Array
    leetcode Remove Element
    leetcode Container With Most Water
    leetcode String to Integer (atoi)
    leetcode Palindrome Number
    leetcode Roman to Integer
    leetcode ZigZag Conversion
  • 原文地址:https://www.cnblogs.com/spencerzhu/p/11341963.html
Copyright © 2011-2022 走看看