Python3多线程方式

多任务介绍

"""
什么是多任务?
操作系统可以同时执行多个任务

现在的操作系统:windows  mac os  linux  unix
这些操作系统  都支持多任务

单核CPU如何实现多任务?
表面看,每个任务都是同时执行,实际上是每个任务在轮询着执行,只是因为CPU的调度太快,导致我们感觉像是所有任务都在同时执行

多核CPU如何实现多任务?
是真正实现了多个任务同时执行

并发:看上去一起执行,任务数大于CPU核心数
并行:一起执行,任务数必须小于等于CPU核心数

实现多任务的方式:
1、多进程方式    
2、多线程方式
3、协程方式
4、多进程+多线程
"""
#没有多进程
import time
def func():
    while True:
        print("this is a process2")
        time.sleep(1.5)
if __name__ == '__main__':
    while True:
        print("this is a process1")
        time.sleep(1)
    func()
"""
multiprocessing 多进程
"""
from multiprocessing import Process
import time,os

def func(str):
    # os.getpid  获取当前进程的进程号
    # os.getppid  获取当前进程的父进程
    while True:
        print("this is process 2--%s--%s--%s"%(str,os.getpid(),os.getppid()))
        time.sleep(1.5)

if __name__ == '__main__':
    print("父进程启动...--%s--%s"%(os.getpid(),os.getppid()))
    # 创建子进程
    # target 说明进程的任务
    p = Process(target=func,args=("python",))
    # 启动进程
    p.start()
    # 主进程中的
    while True:
        print("this is a process 1--%s--%s"%(os.getpid(),os.getppid()))
        time.sleep(1)
# 让父进程等待子进程结束之后父进程再结束
from multiprocessing import Process
from time import sleep

def func():
    print("子进程启动...")
    sleep(3)
    print("子进程结束...")

if __name__ == '__main__':
    print("父进程启动...")
    p = Process(target = func)
    p.start()
    # sleep(1)
    # 让父进程等待子进程结束之后父进程再结束
    # timeout 超时时间   父进程的等待时间
    p.join()
    #执行后一直等待
    print("父进程结束...")
# 在子进程中修改全局变量  对父进程中的全局变量没有影响
from multiprocessing import Process
num = 100
def run1():
    print("孙子进程开始...")
    print("孙子进程结束...%s"%(num))

def run():
    print("子进程开始...")
    global num
    num += 1
    print(num)
    p = Process(target=run1)
    p.start()
    p.join()
    print("子进程结束...")

if __name__ == '__main__':
    print("父进程开始...")
    p = Process(target=run)
    p.start()
    p.join()
    num += 2
    # 在子进程中修改全局变量  对父进程中的全局变量没有影响
    # 我们在创建子进程的时候  对全局变量做了一个备份
    # 子进程和父进程的Num是两个完全不同的变量
    # 所有进程对全局变量的修改  都不会影响其它进程
    print("父进程结束...%d"%(num))
#进程池
from multiprocessing import Pool,Process
import time,random
def foo():
    print("孙子进程开始...")
    print("孙子进程结束...")
def func(name):
    print("子进程%s启动..."%(name))
    start = time.time()
    time.sleep(random.choice([1,2,3]))
    end = time.time()
    print("子进程%s结束...耗时%.2f"%(name,end - start))

if __name__ == '__main__':
    print("父进程开始...")
    # 创建进程池
    # 如果没有参数  默认大小为自己电脑的CPU核心数
    # 表示可以同时执行的进程数量
    pp = Pool(2)
    for i in range(4):
        # 创建进程,放入进程池统一管理
        pp.apply_async(func,args=(i,))
        # 在调用join之前必须先关掉进程池
    # 进程池一旦关闭  就不能再添加新的进程了
    pp.close()
    # 进程池对象调用join,会等待进程池中所有的子进程结束之后再结束父进程
    pp.join()
    print("父进程结束...")

多线程

"""
多线程:

在一个进程内部,要同时干很多事,就需要同时执行多个子任务
那么我们把进程内的这些子任务叫做线程

线程的内存空间是共享的   每个线程都共享同一个进程的资源

模块:
1、_thread模块       低级模块
2、threading模块     高级模块   对_thread模块进行了封装
"""
#创建线程
import threading,time

def run(num):
    print("子线程%s开始..."%(threading.current_thread().name))
    time.sleep(2)
    print(num)
    time.sleep(2)
    # current_thread  返回一个当前线程的实例
    print("子线程%s结束..."%(threading.current_thread().name))
if __name__ == '__main__':
    print("主线程%s启动..."%(threading.current_thread().name))
    # 创建子线程
    t = threading.Thread(target = run,args = (1,))
    t.start()
    t.join()
    print("主线程%s结束..."%(threading.current_thread().name))
#多线程共享资源
import threading

num = 0
var = 0
def run(n):
    global num
    for i in range(1000000):
        num += n
        num -= n
def run1(n):
    global var
    for i in range(100):
        var += n
        var -= n

if __name__ == '__main__':
    t1 = threading.Thread(target=run,args=(6,))
    t2 = threading.Thread(target=run,args=(9,))
    t3 = threading.Thread(target=run,args=(5,))
    t3.start()
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    t3.join()
    print("num = %s"%(num))
# 互斥锁
import threading
# 创建锁对象
lock = threading.Lock()
num = 0

def run(n):
    global num
    for i in range(1000000):
        # 加锁  为了确保下面代码只能由一个线程从头到尾的执行
        # 会阻止多线程的并发执行,所以效率会大大降低
        """
        lock.acquire()
        try:
            num = num - n
            num = num + n
        finally:
            # 解锁
            lock.release()
        """
        with lock:
            num = num + n
            num = num - n

if __name__ == '__main__':
    t1 = threading.Thread(target=run,args=(6,))
    t2 = threading.Thread(target=run,args=(9,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print("num = %s"%(num))
# 信号量
import threading,time
# 信号量
sem = threading.Semaphore(3)

def run():
    with sem:
        for i in range(5):
            print("%s--%d"%(threading.current_thread().name,i))
            time.sleep(1)
if __name__ == '__main__':
    for i in range(5):
        t = threading.Thread(target=run)
        t.start()
# 凑够数量再结束
import threading,time
sem = threading.Semaphore(10)
bar = threading.Barrier(10)# 凑够数量再结束

def run():
    # 先使用指定的信号量
    with sem:
        print("%s--start..."%(threading.current_thread().name))
        time.sleep(1)
        bar.wait()
        print("%s--end..."%(threading.current_thread().name))

if __name__ == '__main__':
    for i in range(21):
        t = threading.Thread(target=run)
        t.start()

网络编程

"""
sock = socket.socket(socket_family,socket_type)
参数:
            socket_family
                socket.AF_INET  适用网络协议的传播,ipv4
                socket.AF_INET6                   ipv6
                socket.AF_UNIX  使用与 unix 系统内部传输,
            socket_type
                socket.SOCK_STREAM  TCP协议
                socket.SOCK_DGRAM   UDP 协议
"""

简单的socket 服务

TCP
#服务器
# 导入模块
import socket
# 创建socket对象   ipv4  TCP协议
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 绑定端口和ip  ip如果为空的话  那么表示绑定所有ip
# 127.0.0.1  表示本机地址
sock.bind(("",9876))
# 设置监听
sock.listen(3)
print("服务器已经启动....")
# 接收消息  进入被动阻塞式接受
# con接收sock对象  add接收ip和端口号
con,add = sock.accept()
print(con)
print(add)
print("%s 已经连接成功..."%(add[0]))

recvs = con.recv(512)
print(recvs.decode("utf-8"))

sends = input(">>>>")
con.send(sends.encode("utf-8"))
sock.close()
#客户
import socket
# 必须和服务端的协议保持一致
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 连接服务器
sock.connect(("127.0.0.1",9876))
# 发送消息
sends = input(">>>>")
sock.send(sends.encode("utf-8"))
# 接收消息
recvs = sock.recv(512)
print(recvs.decode("utf-8"))
sock.close()
UDP
#服务器
import socket
# 创建socket对象       ipv4             UDP协议
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

sock.bind(("",8010))
print("服务器已经启动....")
while True:
    # con 接收传输过来的数据
    # add ip和端口号
    con,add = sock.recvfrom(512)
    print(con)
    print(add)
    print("%s 连接成功..."%(add[0]))
    print(con.decode("utf-8"))
    if con.decode("utf-8") == "break":
        break
    sends = input(">>>")
    # 第一个参数是要发送的信息
    # 第二个参数是接收方的ip和端口号
    sock.sendto(sends.encode("utf-8"),("127.0.0.1",8011))
    if sends == "break":
        break
sock.close()
#客户
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

sock.bind(("",8011))

while True:
    sends = input(">>>>")
    sock.sendto(sends.encode("utf-8"),("127.0.0.1",8010))
    if sends == "break":
        break
    con,add = sock.recvfrom(512)
    print(con.decode("utf-8"))
    if con.decode("utf-8") == "break":
        break
sock.close()

给飞Q发消息

#给飞Q好友发消息
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# sock.bind(("",8010))
sends = "1_lbt4_10#32499#002481627512#0#0#0:1289671407:a:b:288:呵呵哒~~~"
for i in range(256):
    ip = "192.168.13.%d"%(i)#自己局域网ip
    print(ip)
    sock.sendto(sends.encode("gbk"),(ip,2425))
sock.close()

用户聊天

#聊天室服务器
import tkinter
import socket
import threading

win = tkinter.Tk()
win.title("QQ聊天室")
win.geometry("500x500+200+100")

users = {}
# 接收客户端发送过来的消息
def run(ck,ca):
    global user
    # print("**********")
    # 接收消息
    userName = ck.recv(1024)
    # 创建一个字典 key为客户端的用户名  value为socket对象
    users[userName.decode("utf-8")] = ck
    # print(users)
    while True:
        # 接收消息
        rData = ck.recv(1024)
        # 将消息进行编码
        dataStr = rData.decode("utf-8")
        # 将接收到的消息进行切分
        infolist = dataStr.split(":")
        # 将消息发送给指定的好友
        users[infolist[0]].send((userName.decode("utf-8")+":"+infolist[1]+"\n").encode("utf-8"))

def starts():
    ipStr = eip.get()
    # 获取端口号
    portStr = eport.get()
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(("", int(portStr)))
    server.listen(10)
    printStr = "服务器已启动...\n"
    text.insert(tkinter.INSERT, printStr)
    while True:
        ck, ca = server.accept()
        # 启动一个线程来连接客户端
        t = threading.Thread(target=run, args=(ck, ca))
        t.start()
        printStrs = "%s 连接成功...\n"%(ca[0])
        text.insert(tkinter.INSERT,printStrs)

def startserver():
    # 启动一个线程来启动服务端
    s = threading.Thread(target=starts)
    s.start()

labelIp = tkinter.Label(win,text = "ip")
labelPort = tkinter.Label(win,text = "port")

eip = tkinter.Variable()
eport = tkinter.Variable()
entryIp = tkinter.Entry(win,textvariable = eip)
entryPort = tkinter.Entry(win,textvariable = eport)

button = tkinter.Button(win,text = "启动",command = startserver)
text = tkinter.Text(win,width = 30,height = 10)

labelIp.grid(row = 0,column = 0)
entryIp.grid(row = 0,column = 1)

labelPort.grid(row = 1,column = 0)
entryPort.grid(row = 1,column = 1)

button.grid(row = 2,column = 1)
text.grid(row = 3,column = 0)

win.mainloop()
#聊天室客户端
#可以创建多个用户
import threading
import tkinter
import socket

win = tkinter.Tk()
win.title("QQ客户端")
win.geometry("500x500+200+100")

ck = None
def getInfo():
    while True:
        # 接收信息
        data = ck.recv(1024)
        text.insert(tkinter.INSERT,data.decode("utf-8"))

def sendMail():
    # 获取好友名
    friend = efriend.get()
    # 获取要发送的消息
    sendStr = esend.get()
    # 进行拼接
    sendStr = friend + ":" + sendStr
    # 发送拼接后的消息
    ck.send(sendStr.encode("utf-8"))

def connectServer():
    global ck
    # 获取用户名
    userStr = euser.get()
    # 获取ip
    ipStr = eip.get()
    # 获取端口号
    portStr = eport.get()
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 连接指定的服务器
    client.connect((ipStr,int(portStr)))
    # 向服务器发送消息
    client.send(userStr.encode("utf-8"))
    ck = client
    # 等待接收消息
    t = threading.Thread(target=getInfo)
    t.start()

labelUser = tkinter.Label(win,text = "userName")
euser = tkinter.Variable()
entryUser = tkinter.Entry(win,textvariable = euser)
labelUser.grid(row = 0,column = 0)
entryUser.grid(row = 0,column = 1)

labelIp = tkinter.Label(win,text = "ip")
eip = tkinter.Variable()
entryIp = tkinter.Entry(win,textvariable = eip)
labelIp.grid(row = 1,column = 0)
entryIp.grid(row = 1,column = 1)

labelPort = tkinter.Label(win,text = "port")
eport = tkinter.Variable()
entryPort = tkinter.Entry(win,textvariable = eport)
labelPort.grid(row = 2,column = 0)
entryPort.grid(row = 2,column = 1)

button1 = tkinter.Button(win,text = "登陆",command = connectServer)
button1.grid(row = 3,column = 1)

text = tkinter.Text(win,width = 30,height = 10)
text.grid(row = 4,column = 0)

esend = tkinter.Variable()
entrySend = tkinter.Entry(win,textvariable = esend)
entrySend.grid(row = 6,column = 0)

efriend = tkinter.Variable()
labelFriend = tkinter.Label(win,text = "好友")
entryFriend = tkinter.Entry(win,textvariable = efriend)
entryFriend.grid(row = 5,column = 0)
labelFriend.grid(row = 5,column = 1)

button2 = tkinter.Button(win,text = "发送",command = sendMail)
button2.grid(row = 6,column = 1)

win.mainloop()

验证短信的发送

#接口类型:互亿无线触发短信接口,支持发送验证码短信、订单通知短信等。
#账户注册:请通过该地址开通账户http://sms.ihuyi.com/register.html
#注意事项:
#(1)调试期间,请用默认的模板进行测试,默认模板详见接口文档;
#(2)请使用APIID(查看APIID请登录用户中心->验证码短信->产品总览->APIID)及 APIkey来调用接口;
#(3)该代码仅供接入互亿无线短信接口参考使用,客户可根据实际需要自行编写;

#!/usr/local/bin/python
#-*- coding:utf-8 -*-
import http.client
import urllib
import time

host  = "106.ihuyi.com"
sms_send_uri = "/webservice/sms.php?method=Submit"

#用户名是登录用户中心->验证码短信->产品总览->APIID
account  = "C1818****"
#密码 查看密码请登录用户中心->验证码短信->产品总览->APIKEY
password = "7ce375e0021eabad7631fd90595c25b1"

def send_sms(text, mobile):
    params = urllib.parse.urlencode({'account': account, 'password' : password, 'content': text, 'mobile':mobile,'format':'json' })
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    conn = http.client.HTTPConnection(host, port=80, timeout=30)
    conn.request("POST", sms_send_uri, params, headers)
    response = conn.getresponse()
    response_str = response.read()
    conn.close()
    return response_str

if __name__ == '__main__':

    mobile = "133********"
    text = "您的验证码是:741741。请不要把验证码泄露给其他人。"
    while True:
        print(send_sms(text, mobile))
        time.sleep(1)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 网络编程 一.楔子 你现在已经学会了写python代码,假如你写了两个python文件a.py和b.py,分别去运...
    go以恒阅读 1,987评论 0 6
  • 身无灵魂双飞翼,心有灵犀一点通 。思念如海每天向无尽的世界扩散,记忆如风不觉来回两渡玉门关。今天仿若给俺再看见...
    灵魂渡劫阅读 267评论 0 0
  • 作者大野耐一,被誉为“日本复活之父“,“穿着工装的圣贤” “生产管理的教父”,丰田纺织公司和丰田合成公司会长。 现...
    苏老夫子阅读 570评论 4 12
  • 金秋送爽,举国欢庆,值此国庆节来临之际,我们祝您阖家幸福安康! 为了让您的孩子与家人一起度过一个平安、健康、文明的...
    lW平淡是真阅读 961评论 0 0