• 线程与进程


    线程的概念

    线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务,在单个程序中同时运行多个线程完成不同的工作,称为多线程

    进程的概念

    进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。

    线程和进程的区别

    进程间是独立的,这表现在内存空间,上下文环境;线程运行在进程空间内。 一般来讲进程是无法突破进程边界存取其他进程内的存储空间;而线程由于处于进程空间内,所以同一进程所产生的线程共享同一内存空间。 同一进程中的两段代码不能够同时执行,除非引入线程。 线程是属于进程的,当进程退出时该进程所产生的线程都会被强制退出并清除。 线程占用的资源要少于进程所占用的资源。 进程和线程都可以有优先级。 在线程系统中进程也是一个线程。可以将进程理解为一个程序的第一个线程。

    线程的调用方式

    直接调用

     1 import threading
     2 import time
     3 def haha(num):
     4     print("running thread:%s" %num)
     5     time.sleep(3)
     6 
     7 if __name__ == "__main__":
     8     t1 = threading.Thread(target=haha,args=(1,)) #生成一个线程实例,执行sayhi,参数args
     9     t2 = threading.Thread(target=haha,args=(2,)) #生成另一个线程实例
    10 
    11     t1.start() #启动线程
    12     t2.start() #启动另一个线程
    13 
    14     print(t1.getName()) #获取线程名
    15     print(t2.getName())

    间接调用

     1 import threading
     2 import time
     3 
     4 class MyThread(threading.Thread):
     5     def __init__(self,num):
     6         threading.Thread.__init__(self)
     7         self.num = num
     8 
     9     def run(self): #定义每个线程要运行的函数,必须是run
    10         print("running thread:%s" %self.num)
    11         time.sleep(3)
    12 
    13 if __name__ == "__main__":
    14     t1 = MyThread(1)
    15     t2 = MyThread(2)
    16     t1.start()
    17     t2.start()

    循环生成10个线程

     1 import threading
     2 import time
     3 
     4 def sayhi(num): #定义每个线程要运行的函数
     5     print("running on number:%s" %num)
     6     time.sleep(3)
     7 
     8 if __name__ == '__main__':
     9      t_list = []
    10      for i in range (10):
    11          t = threading.Thread(target=sayhi,args=[i,])
    12          t.start()
    13          t_list.append(t)
    14      for i in t_list:
    15          i.join()
    16      print('---main---')

    join,等待线程执行完

     1 import threading
     2 import time
     3 
     4 def sayhi(num): #定义每个线程要运行的函数
     5     print("running on number:%s" %num)
     6     time.sleep(3)
     7 
     8 if __name__ == '__main__':
     9 
    10     t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例
    11     t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例
    12 
    13     t1.start() #启动线程
    14     t2.start() #启动另一个线程
    15 
    16     print(t1.getName()) #获取线程名
    17     print(t2.getName())
    18     
    19     t1.join() #t1.wait() 等待线程执行完
    20     t2.join() #t2.wait()
    21     
    22     print('---main---') #等线程执行完打印,如果不加join,会同线程执行的同时打印
    setDaemon(守护线程)
     1 import time
     2 import threading
     3 
     4 def run(n):
     5 
     6     print('[%s]------running----
    ' % n)
     7     time.sleep(2)
     8     print('--done--')
     9 
    10 def main():
    11     for i in range(5):
    12         t = threading.Thread(target=run,args=[i,])
    13         t.start()
    14         print('starting thread', t.getName())
    15 
    16 
    17 m = threading.Thread(target=main,args=[])
    18 m.setDaemon(True) #将主线程设置为Daemon线程,它退出时,其它子线程会同时退出,不管是否执行完任务
    19 m.start()
    20 print("---main thread done----")

    线程锁

    生成100个线程,去修改一个公共变量num=100,每次进行减一操作,最后结果应该等于0,但事实并非如此,由于两个线程是并发同时运行,所以两个线程可能会取得同一个数进行操作,如,前两个线程可能同时取得100,对其减一,结果为99,并非是98。

     1 import time
     2 import threading
     3 
     4 def addNum():
     5     global num #在每个线程中都获取这个全局变量
     6     print('--get num:',num )
     7     time.sleep(1)
     8     num  -=1 #对此公共变量进行-1操作
     9 
    10 num = 100  #设定一个共享变量
    11 thread_list = []
    12 for i in range(100):
    13     t = threading.Thread(target=addNum)
    14     t.start()
    15     thread_list.append(t)
    16 
    17 for t in thread_list: #等待所有线程执行完毕
    18     t.join()
    19 
    20 print('final num:', num )

    添加线程锁,线程在操作公共变量时对其加锁,使其他线程无法修改,待该线程对其修改完,再对其进行解锁

     1 import time
     2 import threading
     3 
     4 def addNum():
     5     global num #在每个线程中都获取这个全局变量
     6     print('--get num:',num )
     7     time.sleep(1)
     8     lock.acquire() #修改数据前加锁
     9     num  -=1 #对此公共变量进行-1操作
    10     lock.release() #修改后解锁
    11 
    12 num = 100  #设定一个共享变量
    13 thread_list = []
    14 lock = threading.Lock() #生成全局锁
    15 for i in range(100):
    16     t = threading.Thread(target=addNum)
    17     t.start()
    18     thread_list.append(t)
    19 
    20 for t in thread_list: #等待所有线程执行完毕
    21     t.join()
    22 
    23 print('final num:', num )

    递归锁

     1 import threading,time
     2  
     3 def run1():
     4     print("grab the first part data")
     5     lock.acquire()
     6     global num
     7     num +=1
     8     lock.release()
     9     return num
    10 def run2():
    11     print("grab the second part data")
    12     lock.acquire()
    13     global  num2
    14     num2+=1
    15     lock.release()
    16     return num2
    17 def run3():
    18     lock.acquire()
    19     res = run1()
    20     print('--------between run1 and run2-----')
    21     res2 = run2()
    22     lock.release()
    23     print(res,res2)
    24  
    25  
    26 if __name__ == '__main__':
    27  
    28     num,num2 = 0,0
    29     lock = threading.RLock()
    30     for i in range(10):
    31         t = threading.Thread(target=run3)
    32         t.start()
    33  
    34 while threading.active_count() != 1:
    35     print(threading.active_count())
    36 else:
    37     print('----all threads done---')
    38     print(num,num2)

    Semaphore(信号量)

    多个线程同时运行

     1 import threading,time
     2 
     3 def run(n):
     4     semaphore.acquire()
     5     time.sleep(1)
     6     print("run the thread: %s
    " %n)
     7     semaphore.release()
     8 
     9 if __name__ == '__main__':
    10 
    11     num= 0
    12     semaphore  = threading.BoundedSemaphore(3) #最多允许3个线程同时运行
    13     for i in range(20):
    14         t = threading.Thread(target=run,args=(i,))
    15         t.start()
    16 
    17 while threading.active_count() != 1:
    18     pass #print threading.active_count()
    19 else:
    20     print('----all threads done---')
    21     print(num)

    Events

    线程间交互,生成三辆车和一个红灯,实现红灯停绿灯行的功能

     1 import threading,time
     2 import random
     3 def light():
     4     if not event.isSet():
     5         event.set() #wait就不阻塞 #绿灯状态
     6     count = 0
     7     while True:
     8         if count < 10:
     9             print('33[42;1m--green light on---33[0m')
    10         elif count <13:
    11             print('33[43;1m--yellow light on---33[0m')
    12         elif count <20:
    13             if event.isSet():
    14                 event.clear()
    15             print('33[41;1m--red light on---33[0m')
    16         else:
    17             count = 0
    18             event.set() #打开绿灯
    19         time.sleep(1)
    20         count +=1
    21 # def car1(n):
    22 #     while 1:
    23 #         time.sleep(random.randrange(10))  #随机几秒
    24 #         if  event.isSet(): #绿灯
    25 #             print("car [%s] is running.." % n)
    26 #         else:
    27 #             print("car [%s] is waiting for the red light.." %n)
    28 
    29 def car(n):  #无bug
    30     while 1:
    31         time.sleep(1)
    32         if  event.isSet(): #绿灯
    33             print("car [%s] is running.." % n)
    34         else:
    35             print("car [%s] is waiting for the red light.." %n)
    36             event.wait()
    37 
    38 if __name__ == '__main__':
    39     event = threading.Event()
    40     Light = threading.Thread(target=light)
    41     Light.start()
    42     for i in range(3):
    43         t = threading.Thread(target=car,args=(i,))
    44         t.start()

    进程

    进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体

    启动两个进程

     1 from multiprocessing import Process
     2 import time
     3 def f(name):
     4     time.sleep(2)
     5     print('hello',name)
     6 
     7 if __name__ == '__main__':
     8     p = Process(target=f,args=('bob',))
     9     p2 = Process(target=f,args=('bob',))
    10     p.start()
    11     p2.start()
    12     p.join()
    13     p2.join()

     显示进程id

     1 from multiprocessing import Process
     2 import os
     3 
     4 def info(title):
     5     print(title)
     6     print('module name:', __name__)
     7     print('parent process:', os.getppid())
     8     print('process id:', os.getpid())
     9     print("
    ")
    10 
    11 if __name__ == '__main__':
    12     info('33[32;1mmain process line33[0m')
    13     p = Process(target=info, args=('bob',))
    14     p.start()
    15     p.join()
    16 
    17 #显示结果
    18 """
    19 main process line
    20 module name: __main__
    21 parent process: 5228
    22 process id: 6628
    23 
    24 
    25 bob
    26 module name: __mp_main__
    27 parent process: 6628
    28 process id: 6908
    29 """

    进程间的数据共享

    queue

     1 from multiprocessing import Process, Queue
     2 
     3 def f(q):
     4     q.put([42, None, 'hello'])
     5 
     6 if __name__ == '__main__':
     7     q = Queue()  #queue队列,先进先出
     8     p = Process(target=f, args=(q,))
     9     p2 = Process(target=f, args=(q,))
    10     p.start()
    11     p2.start()
    12     print(q.get())    # print "[42, None, 'hello']"
    13     print(q.get())    #先进先出
    14     p.join()

    pipes,双向队列

     1 from multiprocessing import Process, Pipe
     2 
     3 def f(conn):
     4     conn.send([42, None, 'hello'])
     5     conn.close()
     6 
     7 if __name__ == '__main__':
     8     parent_conn, child_conn = Pipe()
     9     p = Process(target=f, args=(child_conn,))
    10     p.start()
    11     print(parent_conn.recv())   # print "[42, None, 'hello']"
    12     p.join()

    manager

     1 from multiprocessing import Process, Manager
     2 
     3 def f(d, l):
     4     d[1] = '1'
     5     d['2'] = 2
     6     d[0.25] = None
     7     l.append(1)
     8     print(l)
     9 
    10 if __name__ == '__main__':
    11     with Manager() as manager:
    12         d = manager.dict()
    13         l = manager.list(range(5))
    14         p_list = []
    15         for i in range(10):
    16             p = Process(target=f, args=(d, l))
    17             p.start()
    18             p_list.append(p)
    19         for res in p_list:
    20             res.join()
    21 
    22         print(d)
    23         print(l)

    进程同步

     1 from multiprocessing import Process, Lock
     2 
     3 def f(l, i):
     4     l.acquire()
     5     try:
     6         print('hello world', i)
     7     finally:
     8         l.release()
     9 
    10 if __name__ == '__main__':
    11     lock = Lock()
    12 
    13     for num in range(10):
    14         Process(target=f, args=(lock, num)).start()

    进程池

     1 from  multiprocessing import Process,Pool,freeze_support
     2 import time
     3 
     4 def Foo(i):
     5     time.sleep(2)
     6     return i+100
     7 
     8 def Bar(arg):
     9     print('-->exec done:',arg)
    10 
    11 
    12 if __name__ == '__main__':
    13     freeze_support()
    14     pool = Pool(5)  #5个一起运行
    15 
    16     for i in range(10):
    17         pool.apply_async(func=Foo, args=(i,),callback=Bar) #回调,执行完foo执行bar
    18         #pool.apply(func=Foo, args=(i,))  #同步
    19 
    20     print('end')
    21     pool.close()
    22     pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。






  • 相关阅读:
    docker知识3---镜像
    docker知识2---docker简介
    docker知识1---容器背景
    docker故障排查
    linux故障处理--ssh故障
    sqlalchemy的一行代码更新数据库
    Python内置函数和高阶函数(map,filter,reduce, sorted,enumerate, zip,单行条件语句 )
    Mysql略复杂命令总结
    pip的使用
    Linux的基础命令
  • 原文地址:https://www.cnblogs.com/yoyovip/p/5756972.html
Copyright © 2020-2023  润新知