python基础语法补充:线程、进程与窗口编程

定义main函数的语句

if __name__=='__main__':

一、python多线程编程

1.导入模块:

import threading

2.获取已激活的线程数

threading.active_count()

3.查看所有线程信息

threading.enumerate()
# [<_MainThread(MainThread, started 140736011932608)>, <Thread(SockThread, started daemon 123145376751616)>]

4.查看现在正在运行的线程

threading.current_thread()
# <_MainThread(MainThread, started 140736011932608)>

5.添加线程

threading.Thread()接收参数target代表这个线程要完成的任务,需自行定义
thread = threading.Thread(target=thread_job,)   # 定义线程
thread.start()  # 让线程开始工作

6.join功能
Thread.join() 作用为阻塞主线程main,即在子线程未返回的时候,主线程等待其返回然后再继续执行.
若不加入join,则会导致线程任务还未完成便输出all done。如果要遵循顺序,可以在启动线程后对它调用join:

added_thread.start()
added_thread.join()
print("all done\n")

使用join对控制多个线程的执行顺序非常关键。举个例子,假设我们现在再加一个线程T2,T2的任务量较小,会比T1更快完成,则会导致顺序错乱。
所以需要:

thread_1.start()
thread_1.join() # notice the difference!
thread_2.start()
print("all done\n")

具体例子:
为了规避不必要的麻烦,推荐如下这种1221的V型排布:

thread_1.start() # start T1
thread_2.start() # start T2
thread_2.join() # join for T2
thread_1.join() # join for T1
print("all done\n")
"""
T1 start
T2 start
T2 finish
T1 finish
all done
"""

7.储存进程结果队列
使用队列的原因:多线程调用的函数不能用return返回值
导入线程,队列的标准模块

from queue import Queue
q.put(l)   #q为一个对队列,将列表l加到队列里。  

在多线程函数中定义一个Queue,用来保存返回值,代替return,定义一个多线程列表,初始化一个多维数据列表,用来处理:

def multithreading():
    q =Queue()    #q中存放返回值,代替return的返回值
    threads = []
    data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]]

在多线程函数中定义四个线程,启动线程,将每个线程添加到多线程的列表中

for i in range(4):   #定义四个线程
    t = threading.Thread(target=job,args=(data[i],q)) #Thread首字母要大写,被调用的job函数没有括号,只是一个索引,参数在后面
    t.start()#开始线程
    threads.append(t) #把每个线程append到线程列表中

分别join四个线程到主线程

for thread in threads:
    thread.join()

定义一个空的列表results,将四个线运行后保存在队列中的结果返回给空列表

results
results = []
for _ in range(4):
    results.append(q.get())  #q.get()按顺序从q中拿出一个值
print(results)

注:错误写法:

for thread in threads:
    thread.start()
    thread.join()

原因:执行join之后,主线程被线程1阻塞,在线程1返回结果之前,主线程无法执行下一轮循环.
正确写法:

for thread in threads:
    thread.start()
for thread in threads:
    thread.join()

8.解释器被一个全局解释器GIL锁保护着,它确保任何时候都只有一个Python线程执行。 GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势 。
GIL只会影响到那些严重依赖CPU的程序(比如计算型的)。
如果你的程序大部分只会涉及到I/O,比如网络交互,那么使用多线程就很合适, 因为它们大部分时间都在等待。

9.lock锁
在每个线程执行运算修改共享内存之前,执行lock.acquire()将共享内存上锁, 确保当前线程执行时,内存不会被其他线程访问,
执行运算完毕后,使用lock.release()将锁打开, 保证其他的线程可以使用该共享内存。
主函数中定义一个Lock

if __name__== '__main__':
    lock=threading.Lock()

函数一和函数二加锁

def job1():
    global A,lock
    lock.acquire()
    for i in range(10):
        A+=1
        print('job1',A)
    lock.release()

def job2():
    global A,lock
    lock.acquire()
    for i in range(10):
        A+=10
        print('job2',A)
    lock.release()

二、python多进程编程

1.导入线程进程标准模块

import multiprocessing as mp

创建线程和进程

t1 = td.Thread(target=job,args=(1,2))
p1 = mp.Process(target=job,args=(1,2))

分别启动线程和进程
t1.start()
p1.start()

分别连接线程和进程
t1.join()
p1.join()

例子:

if __name__=='__main__':
    p1 = mp.Process(target=job,args=(1,2))
    p1.start()
    p1.join()
三、python窗口编程

1.定义 window 窗口 和 window的一些属性, 然后书写窗口内容, 最后执行

window.mainloop让窗口活起来.
import tkinter as tk
window = tk.Tk()
window.title('my window')
window.geometry('200x100')

这里是窗口的内容

window.mainloop()

2.这次我们会建立一个用来描述的标签 tk.Label,
比如:

l = tk.Label(window, 
    text='OMG! this is TK!',    # 标签的文字
    bg='green',     # 背景颜色
    font=('Arial', 12),     # 字体和字体大小
    width=15, height=2  # 标签长宽
    )

l.pack() # 固定窗口位置

3.引入按钮 tk.Button 的概念, 没点一次按钮, 标签变化一次. 用一下内容替换上面的标签.
把需要变化的文字存成变量 var:

var = tk.StringVar()    # 这时文字变量储存器
l = tk.Label(window, 
    textvariable=var,   # 使用 textvariable 替换 text, 因为这个可以变化
    bg='green', font=('Arial', 12), width=15, height=2)
l.pack() 

接着我们来做 按钮 tk.Button:

b = tk.Button(window, 
    text='hit me',      # 显示在按钮上的文字
    width=15, height=2, 
    command=hit_me)     # 点击按钮式执行的命令
b.pack()    # 按钮位置

那么点击是的命令我们用 if else 语句来判断. 用 on_hit 来判断当前状态.

on_hit = False  # 默认初始状态为 False
def hit_me():
    global on_hit
    if on_hit == False:     # 从 False 状态变成 True 状态
        on_hit = True
        var.set('you hit me')   # 设置标签的文字为 'you hit me'
    else:       # 从 True 状态变成 False 状态
        on_hit = False
        var.set('') # 设置 文字为空
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值