python---线程与进程

一 线程

1.1 概述

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

Threading用于提供线程相关的操作:

import threading
import time

def show(arg):
    time.sleep(1)
    print ('thread'+str(arg))

for i in range(10):
    t = threading.Thread(target=show, args=(i,))
    t.start()

print ('main thread stop')

>>>main thread stop
>>>thread0
>>>thread6
>>>thread3
>>>thread2
>>>thread5
>>>thread4
>>>thread1
>>>thread7
>>>thread8
>>>thread9

上述代码创建了10个“前台”线程,然后控制器就交给了CPU,CPU根据指定算法进行调度,分片执行指令。

注:后台线程行为: 只要你的主线程执行完毕了,后台线程,不管你执行到哪里了,就直接关闭了。前台线程行为: 主程序执行过程中,前台线程也在执行,主程序执行完毕后,等待前台线程也执行完成后,程序结束。

start         #线程准备就绪,等待CPU调度
setName       #为线程设置名称
getName       #获取线程名称
setDaemon     #设置为后台线程或前台线程(默认),如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止 如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
join           #逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
run            #线程被cpu调度后自动执行线程对象的run方法
更多方法

1.2 线程锁(Lock,RLock)

  由于线程之间是进行随机调度,并且每个线程可能只执行n条执行之后,当多个线程同时修改同一条数据时可能会出现脏数据,所以,出现了线程锁 - 同一时刻允许一个线程执行操作。

import threading
import time

gl_num = 0

def show(arg):
    global gl_num
    time.sleep(1)
    gl_num +=1
    print (gl_num,end=' ')

for i in range(10):
    t = threading.Thread(target=show, args=(i,))
    t.start()

print ('main thread stop')

>>>main thread stop
>>>1 2 3 4 5 6 7 8 9 10 
未使用锁
import threading
import time

gl_num = 0

lock = threading.RLock()

def Func():
    lock.acquire()
    global gl_num
    gl_num +=1
    time.sleep(1)
    print (gl_num)
    lock.release()

for i in range(10):
    t = threading.Thread(target=Func)
    t.start()
线程锁

1.3 信号量(semaphore)

  多线程编程的最常见问题是数据共享。当多个线程都修改某一个共享数据的时候,需要进行同步控制。线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。互斥锁为资源引入一个状态:锁定/非锁定。某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

  而互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。

import threading,time

def run(n):
    semaphore.acquire()
    time.sleep(2)
    print("run the thread: %s" %n)
    semaphore.release()

if __name__ == '__main__':

    num= 0
    semaphore  = threading.BoundedSemaphore(5) #最多允许5个线程同时运行
    for i in range(20):
        t = threading.Thread(target=run,args=(i,))
        t.start()

1.4 事件(event)

  python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。事件处理的机制:全局定义了一个“Flag”,clear将“Flag”设置为False,set将“Flag”设置为True。如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。

import threading

def do(event):
    print ('start')
    event.wait()
    print ('execute')

event_obj = threading.Event()
for i in range(10):
    t = threading.Thread(target=do, args=(event_obj,))
    t.start()

event_obj.clear()
inp = input('input:')
if inp == 'true':
    event_obj.set()

1.5 timer

定时器,指定n秒后执行某操作

from threading import Timer

def hello():
    print("hello, world")

t = Timer(1, hello)
t.start()  # after 1 seconds, "hello, world" will be printed

二 进程

2.1 进程的创建

from multiprocessing import  Process
import time

def worker(interval):
    n = 5
    while n > 0:
        print("The time is {0}".format(time.ctime()))
        time.sleep(interval)
        n -= 1

if __name__ == "__main__":
    p = Process(target = worker, args = (3,))
    p.start()
    print ("p.pid:", p.pid)
    print ("p.name:", p.name)
    print ("p.is_alive:", p.is_alive())


>>>p.pid: 5360
>>>p.name: Process-1
>>>p.is_alive: True
>>>The time is Thu Jul 12 18:57:23 2018
>>>The time is Thu Jul 12 18:57:26 2018
>>>The time is Thu Jul 12 18:57:29 2018
>>>The time is Thu Jul 12 18:57:32 2018
>>>The time is Thu Jul 12 18:57:35 2018
单进程
import multiprocessing
import time

def worker_1(interval):
    print ("worker_1")
    time.sleep(interval)
    print ("end worker_1")

def worker_2(interval):
    print ("worker_2")
    time.sleep(interval)
    print ("end worker_2")

def worker_3(interval):
    print ("worker_3")
    time.sleep(interval)
    print ("end worker_3")

if __name__ == "__main__":
    p1 = multiprocessing.Process(target = worker_1, args = (2,))
    p2 = multiprocessing.Process(target = worker_2, args = (3,))
    p3 = multiprocessing.Process(target = worker_3, args = (4,))

    p1.start()
    p2.start()
    p3.start()

    print("The number of CPU is:" + str(multiprocessing.cpu_count()))
    for p in multiprocessing.active_children():
        print("child   p.name:" + p.name + "\tp.id" + str(p.pid))
    print ("END!!!!!!!!!!!!!!!!!")

>>>The number of CPU is:4
>>>child   p.name:Process-1    p.id5196
>>>child   p.name:Process-2    p.id8680
>>>child   p.name:Process-3    p.id2732
>>>END!!!!!!!!!!!!!!!!!
>>>worker_2
>>>worker_1
>>>worker_3
>>>end worker_1
>>>end worker_2
>>>end worker_3
多进程

注意:(1)由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。

   (2)进程各自持有一份数据,默认无法共享数据

2.2 daemon

  子进程设置了daemon属性时,主进程结束,它们就随着结束了。(线程也有deamon操作)

import multiprocessing
import time

def worker(interval):
    print("work start:{0}".format(time.ctime()));
    time.sleep(interval)
    print("work end:{0}".format(time.ctime()));

if __name__ == "__main__":
    p = multiprocessing.Process(target = worker, args = (3,))
    p.start()
    print ("end!")

>>>end!
>>>work start:Thu Jul 12 19:12:51 2018
>>>work end:Thu Jul 12 19:12:54 2018
不加deamon
import multiprocessing
import time

def worker(interval):
    print("work start:{0}".format(time.ctime()));
    time.sleep(interval)
    print("work end:{0}".format(time.ctime()));

if __name__ == "__main__":
    p = multiprocessing.Process(target = worker, args = (3,))
    p.daemon = True
    p.start()
    print ("end!")

>>>end!
有deamon

 参考:https://www.cnblogs.com/yuanchenqi/articles/5733873.html

   https://www.cnblogs.com/wupeiqi/articles/5040827.html

posted @ 2018-07-12 19:18  珠峰上吹泡泡  阅读(181)  评论(0编辑  收藏  举报