一.多線程能幹什麼:
生產者消費者問題:(經典)
一直生產 一直消費 中間有閥值 避免供求關係不平衡
線程安全問題,要是線程同時來,聽誰的
鎖:一種數據結構 隊列:先進線出 棧:先進後出
生產者消費者的優點(爲什麼經典的設計模式)
1.解耦(讓程序各模塊之間的關聯性降到最低)
假設生產者和消費者是兩個類,如果讓生產者直接調用消費者的某個方法,那麼生產者對於消費者就會產生依賴(也就是耦合),
如果將來消費者的代碼發生變換,可能會影響到生產者,而如果兩者都依賴於某個緩衝區,兩者之間不直接依賴,
耦合也就相應降低了
生活中的例子:我們 郵筒 郵遞員
舉個例子,我們去郵局投遞信件,如果不使用郵筒(也就是緩衝區),你必須得把信直接交給郵遞員,有同學會說,
直接交給郵遞員不是挺簡單的嘛,其實不簡單,你必須得認識郵遞員,才能把信給他(光憑身上的制服,萬一有人假冒呢???),
這就產成你和郵遞員之間的依賴了(相當於生產者消費者強耦合),萬一哪天郵遞員換人了,
你還要重新認識一下(相當於消費者變化導致修改生產者代碼),而郵筒相對來說比較固定,
你依賴它的成本就比較低(相當於和緩衝區之間的弱耦合)
2.支持併發
生產者消費者是兩個獨立的併發體,他們之間是用緩衝區作爲橋樑連接,生
產者之需要往緩衝區裏丟數據,就可以繼續生產下一個數據,而消費者者只需要從緩衝區裏拿數據即可,
這樣就不會因爲彼此速度而發生阻塞
接着上面的例子:如果我們不使用郵筒,我們就得在郵局等郵遞員,直到他回來了,我
們才能把信給他,這期間我們啥也不能幹(也就是產生阻塞),或者郵遞員挨家挨戶的問(產生論尋)
3.支持忙閒不均
如果製造數據的速度時快時慢,緩衝區的好處就體現出來了,當數據製造快的時候,
消費者來不及處理,未處理的數據可以暫時存在緩衝區中,等生產者的速度慢下來,
消費者再慢慢處理
情人節信件太多了,郵遞員一次處理不了,可以放在郵筒中,下次在來取
“”“pymsql是Python中操作MySQL的模塊,其使用方法和MySQLdb幾乎相同。但目前pymysql支持python3.x而後者不支持3.x版本。
示例一
import MySQLdb
# 打開門
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='dd',db='python')
# 伸出手
cur = conn.cursor()
# 拿東西
recont = cur.execute('select * from userInfo')
# 把手伸回來
cur.close()
# 把門關上
conn.close()
print recont
示例二
import MySQLdb
# 打開門
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='dd',db='python')
# 伸出手
#cur = conn.cursor() #創建了一個“手”
# 拿到數據庫的表頭
cur = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)
# 拿東西
# 這個操作影響了多少行數(有多少行被操作了)
recont = cur.execute('select * from userInfo')
data = cur.fetchall()
# 把手伸回來
cur.close()
# 把門關上
conn.close()
print recont
print data
在Mysql中增加內容
import MySQLdb
# 打開門
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='dd',db='python')
# 伸出手
cur = conn.cursor()
# 操作數據
sql = 'insert into usermg(id,name,address) values(%s,%s,%s)'
params = ('1','dd','usa')
recount = cur.execute(sql,params)
# 提交請求
conn.commit()
# 把手伸回來
cur.close()
#把門關上
conn.close()
print recount
在Mysql數據庫中查詢內容
import MySQLdb
# 打開門
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='dd',db='python')
# 伸出手
cur = conn.cursor()
# 操作數據
sql = 'update usermg set name = %s where id = %s'
params = ('uu','1',)
recount = cur.execute(sql,params)
# 提交請求
conn.commit()
# 把手伸回來
cur.close()
#把門關上
conn.close()
print recount
在Mysql數據庫中刪除內容
import MySQLdb
# 打開門
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='dd',db='python')
# 伸出手
cur = conn.cursor()
# 操作數據
sql = 'delete from usermg where id = %s'
params = (1,)
recount = cur.execute(sql,params)
# 提交請求
conn.commit()
# 把手伸回來
cur.close()
#把門關上
conn.close()
print recount
在Myaql數據庫插入多條內容
import MySQLdb
# 打開門
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='dd',db='python')
# 伸出手
cur = conn.cursor()
# 操作數據
# sql = 'update usermg set name = %s where id = %s'
# params = ('uu','1',)
li = [
('2','hahaha','wwww'),
('3','lalala','qqqq'),
]
recount = cur.executemany('insert into usermg(id,name,address) values(%s,%s,%s)',li)
# 提交請求
conn.commit()
# 把手伸回來
cur.close()
#把門關上
conn.close()
print recount
import MySQLdb
#打開門
conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='redhat',db='xiaozhuang')
#伸出手
cur = conn.cursor()
sql = 'update count set money = %s where id = 1 '
params = (0,)
reCount = cur.execute(sql,params)
# conn.commit()
#因爲默認mysql裏是有事務的,所以我們模擬,一步一提交
#如果這裏寫錯(sql語句寫錯),但我上一個賬戶減錢的已經提交
#這時,我們在數據庫裏面可以看到,一個減錢,但一個並沒有加錢
sql = 'update countl set money = %s where id = 2 '
params = (300,)
reCount = cur.execute(sql,params)
conn.commit()
#把手伸回來
cur.close()
#把門關上
二.多線程
多線程能幹什麼:
生產者消費者問題:(經典)
一直生產 一直消費 中間有閥值 避免供求關係不平衡
線程安全問題,要是線程同時來,聽誰的
鎖:一種數據結構 隊列:先進線出 棧:先進後出
生產者消費者的優點(爲什麼經典的設計模式)
1.解耦(讓程序各模塊之間的關聯性降到最低)
假設生產者和消費者是兩個類,如果讓生產者直接調用消費者的某個方法,那麼生產者對於消費者就會產生依賴(也就是耦合),
如果將來消費者的代碼發生變換,可能會影響到生產者,而如果兩者都依賴於某個緩衝區,兩者之間不直接依賴,
耦合也就相應降低了
生活中的例子:我們 郵筒 郵遞員
舉個例子,我們去郵局投遞信件,如果不使用郵筒(也就是緩衝區),你必須得把信直接交給郵遞員,有同學會說,
直接交給郵遞員不是挺簡單的嘛,其實不簡單,你必須得認識郵遞員,才能把信給他(光憑身上的制服,萬一有人假冒呢???),
這就產成你和郵遞員之間的依賴了(相當於生產者消費者強耦合),萬一哪天郵遞員換人了,
你還要重新認識一下(相當於消費者變化導致修改生產者代碼),而郵筒相對來說比較固定,
你依賴它的成本就比較低(相當於和緩衝區之間的弱耦合)
2.支持併發
生產者消費者是兩個獨立的併發體,他們之間是用緩衝區作爲橋樑連接,生
產者之需要往緩衝區裏丟數據,就可以繼續生產下一個數據,而消費者者只需要從緩衝區裏拿數據即可,
這樣就不會因爲彼此速度而發生阻塞
接着上面的例子:如果我們不使用郵筒,我們就得在郵局等郵遞員,直到他回來了,我
們才能把信給他,這期間我們啥也不能幹(也就是產生阻塞),或者郵遞員挨家挨戶的問(產生論尋)
3.支持忙閒不均
如果製造數據的速度時快時慢,緩衝區的好處就體現出來了,當數據製造快的時候,
消費者來不及處理,未處理的數據可以暫時存在緩衝區中,等生產者的速度慢下來,
消費者再慢慢處理
情人節信件太多了,郵遞員一次處理不了,可以放在郵筒中,下次在來取
線程
線程是操作系統能夠進行運算調度的最小單位(程序執行流的最小單元)
它被包含在進程之中,是進程中的實際運作單位。一個進程中可以併發多個線程
每條線程並行執行不同的任務
(線程是進程中的一個實體,是被系統獨立調度和分派的基本單元)
每一個進程啓動時都會最先產生一個線程,即主線程
然後主線程會再創建其他的子線程
“”“
import threading
from time import ctime,sleep
def music(a):
for i in range(2):
print 'I was listening to %s. %s' % (a,ctime())
sleep(1)
def movie(b):
for i in range(2):
print 'I was watching to %s. %s' % (b,ctime())
sleep(5)
#music('告白氣球')
#movie('泰坦尼克號')
thread = []
t1 = threading.Thread(target=music,args=('告白氣球',))
thread.append(t1)
t2 = threading.Thread(target=movie,args=('泰坦尼克號',))
thread.append(t2)
for t in thread:
#t.setDaemon(True)
t.start
print 'all over %s' % ctime()
示例二
from threading import Thread
def Foo(arg):
print arg
print 'before'
# 線程和函數建立關係
t1 = Thread(target=Foo,args=(1,))
t1.start()
print 'after'
示例三
from threading import Thread
def Foo(arg):
print arg
print 'before'
t1 = Thread(target=Foo,args=(1,))
t1.start()
print t1.getName()
t2 = Thread(target=Foo,args=(2,))
t2.start()
print t2.getName()
print 'after'
示例四
from threading import Thread
import time
def Foo():
for item in range(100):
print item
time.sleep(1)
print 'before'
t1 = Thread(target=Foo)
t1.setDaemon(True)
t1.start()
print 'after'
time.sleep(10)
示例五–吃包子
import threading
import Queue
import time
import random
def Producer(name,que):
while True:
if que.qsize() <3:
que.put('baozi')
print '%s:Made a baozi..=============' % name
else:
print '還有三個包子'
time.sleep (random.randrange(5))
def Consumer(name,que):
while True:
try:
que.get_nowait()
print '%s:Got a baozi..' % name
except Exception:
print '沒有包子了'
time.sleep(random.randrange(3))
# 創建隊列
q = Queue.Queue()
p1 = threading.Thread(target=Producer,args=['chef1',q])
p2 = threading.Thread(target=Producer,args=['chef2',q])
p1.start()
p2.start()
c1 = threading.Thread(target=Consumer,args=['tom',q])
c2 = threading.Thread(target=Consumer,args=['harry',q])
c1.start()
c2.start()
示例六–事件驅動
import threading
import time
def Producer():
print 'chef:等人來買包子'
#收到了消費者的event.set 也就是把這個flag改爲了true,但是我們的包子並沒有做好
event.wait()
#此時應該將flag的值改回去
event.clear()
print 'chef:someone is coming for 包子'
print 'chef:making a 包子 for someone'
time.sleep(5)
# 告訴人家包子做好了
print '你的包子好了~'
event.set()
def Consumer():
print 'tom:去買包子'
# 告訴人家我來了
event.set()
time.sleep(2)
print 'tom:waiting for 包子 to be ready'
event.wait()
print '哎呀~真好吃'
event = threading.Event()
p1 = threading.Thread(target=Producer)
c1 = threading.Thread(target=Consumer)
p1.start()
c1.start()
示例七 – 異步
import threading
import time
def Producer():
print 'chef:等人來買包子'
# 收到了消費者的event.set 也就是把這個flag改爲了true,但是我們的包子並沒有做好
event.wait()
# 此時應該將flag的值改回去
event.clear()
print 'chef:someone is coming for 包子'
print 'chef:making a 包子 for someone'
time.sleep(5)
# 告訴人家包子做好了
print '你的包子好了~'
event.set()
def Consumer():
print 'tom:去買包子'
# 告訴人家我來了
event.set()
time.sleep(2)
print 'tom:waiting for 包子 to be ready'
# 我在不斷檢測,但我已經不阻塞了
while True:
if event.is_set():
print 'Thanks~'
break
else:
print '怎麼還沒好呀~'
# 模擬正在做自己的事情
time.sleep(1)
event = threading.Event()
p1 = threading.Thread(target=Producer)
c1 = threading.Thread(target=Consumer)
p1.start()
c1.start()