Python 学习笔记: 多线程

 多线程

1、 多线程的TCP server 聊天

from threading import Thread
import socket

def chat(conn):
    conn.send(b'hello')
    msg = conn.recv(1024).decode('utf-8')
    print(msg)


if __name__ == '__main__':
    sk = socket.socket()
    sk.bind(('127.0.0.1', 8090))
    sk.listen()

    while True:
        conn, addr = sk.accept()
        t = Thread(target=chat, args=(conn,))
        t.start()
    sk.close()

2 、 守护线程, 会等待所有的线程结束才结束

from threading import Thread
import time

def func1():
    print('start thread func...')
    while True:
        print('*'*10)
        time.sleep(1)

def func2():
    print('thread func2 start...')
    time.sleep(4)
    print('thread func2 end...')


t1 = Thread(target=func1,)
t1.daemon = True
t1.start()
t2 = Thread(target=func2,)
t2.start()
print('main thread .')

3、线程的递归锁, 例子: 科学家吃面,利用递归锁解决死锁。

from threading import Thread
from threading import RLock
import time

def eat(name):
    global noodle_rlock
    global fork_rlock
    noodle_rlock.acquire()
    time.sleep(1)
    fork_rlock.acquire()
    print('%s 拿到 noodle lock'%name)
    print('%s 拿到 fork lock'%name)
    print('%s 吃面。。'%name)
    fork_rlock.release()
    noodle_rlock.release()



noodle_rlock = fork_rlock = RLock()
Thread(target=eat,args=('alex',)).start()
Thread(target=eat,args=('jinboss',)).start()
Thread(target=eat,args=('boke',)).start()
Thread(target=eat,args=('kilin',)).start()

4、事件, 连接数据库前,测试连接数据库连接是否成功。

import time
from threading import Thread,Event
import random

def conn_db(e):
    count = 0
    while count < 3:
        e.wait(0.5)
        if e.is_set():
            print('第%s次连接数据库成功'%(count+1))
            break
        else:
            count += 1
            print('第%s次连接数据库失败' %(count))

    else:
        # raise TimeoutError('连接数据库超时')
        print('连接数据库超时')


def check_db(e):
    time.sleep(random.randint(0,4))
    e.set()



e = Event()

t1 = Thread(target=check_db, args=(e,))
t2 = Thread(target=conn_db, args=(e,))
t1.start()
t2.start()

5 条件Condition

from threading import Condition, Thread

def func(con,i):
    con.acquire()
    con.wait()
    print('进程%s %s在执行中...'%(i,Thread.ident))
    con.release()

con = Condition()

for i in range(10):
    Thread(target=func, args=(con,i)).start()
while True:
    num = int(input('>>>>'))
    con.acquire()
    con.notify(num)
    con.release()

例如: 输入3时, con.notify(3) , 发布3把钥匙。 会有3个线程开始执行。

6、线程池 使用concurrent.futures 包

import time
import random
from concurrent.futures import ThreadPoolExecutor

def func(n):
    time.sleep(random.randint(1,3))
    print('in thread %s'%n)
    return n*n

tpool = ThreadPoolExecutor(5)
t_plist=[]

for i in range(20):
    t = tpool.submit(func,i)
    t_plist.append(t)

print('main threading')

tpool.shutdown()
for t in t_plist:
    print('***',t.result())

 

带call back 函数时,返回值是一个结果的对象。 需要result()方法取得结果

import time
from concurrent.futures import ThreadPoolExecutor

def func(n):
    time.sleep(2)
    print('in thread %s'%n)
    return n*n

def call_back(m):
    print('结果是 %s'%m.result())

tpool = ThreadPoolExecutor(5)

for i in range(20):
    tpool.submit(func,i).add_done_callback(call_back)


print('main threading')

 

posted @ 2018-11-29 18:51  程序猿&#127805;  阅读(180)  评论(0编辑  收藏  举报