线程

11 篇文章 0 订阅
8 篇文章 0 订阅

线程

线程是程序运行过程中,执行代码的分支

  • 同步:事情一件件执行
  • 异步:任务间的执行互不干扰,同时执行
  • 并发:异步任务数大于通道数,随便找一个先走,一个个走,只是系统切换任务的速度很快,看起来像是一起运行
  • 并行:异步任务数小于通道数,同时通过,是真的把所有人无一起执行

1.多任务

同一时间执行多个任务,就是多任务的概念,几核就同时运行几个任务,叫cpu的时间线轮转,

2.线程模块threading

Thread类

agrs=(tulpe);kwargs={‘参数名’:参数值}

Thread(group,target=,name,[args,kwarg])

  • 1.创建线程,tread_name = threading.Thread(target = ,)
  • 2.开始线程 tread_name.start()

函数里有*, 后面必须用关键字传参数

如果元组只有一个数字要加一个,(5,)

线程间执行互不干扰,创建线程是相对主线程来说的,创建的都是子线程
线程就是执行代码的分支,代码执行的最小单位,是真正干活的

3.获取活动线程的列表和个数

threading.enumerate() 获取活动线程列表

线程完成任务后会销毁

len(threading.enumerate) /threading.active_count()获取活动线程个数

当前线程:threading.current_thread()

4.注意点

1 . 线程的执行是无序的,就算按照一定顺序创建线程,但是他的执行是无序的

2 . 主线程等待所有子线程执行结束

exit()退出 return()退出函数

守护主线程:主线程结束强制结束子线程

1, 子线程 threading.Thread(,daemon= True)
2, 子线程设置 thread_name.setDaemon(True)

5.自定义线程类

继承threading.Thread封装相关的执行任务,重写run()

不需要用target指定执行某个任务,启动线程统一使用start(),start()里会调用run

如果要传参数,直接在自定义类里调用初始化方法 (def init(self,num1,num2)?,z再手动调用

如果子类提供了init方法,默认不会调用父类方法,需要手动调用父类init方法,才能使用那些父类的属性

( super(CustmThread,self).init() )

6.pycharm快捷注释多行:选中 + command + /

7.线程间可以共享全局变量,但是易出现资源竞争,互斥锁

全局变量加global原因,因为内存变量地址会改变,例如列表append不会改变,就不用加global ! 查看地址 id(变量)

共享全局变量会出现的

共享全局变量的都在取存,会发生疏忽误差

线程等待(同步),线程巩固,表示主线程等待第一个线程执行完,代码才能往下继续执行

多线程同时对全局资源的操作,有可能出现竞争

为了解决全局变量竞争,加入互斥锁

谁抢到这把锁,谁去执行,保证变量数据不发生错乱,对共享变量数据锁定,抱枕同一时刻只有一个访问变量

1.创建互斥锁,threading.Lock()

2.函数内调用锁, looc_name.acquire()

3.释放锁lock_name.release()

死锁

原因就是锁没有释放,或者搞了多个锁,解决办法就是提高代码逻辑,及时关闭锁

8.多线程的应用:

多线程的udp聊天器

一个线程收消息,一个发消息
主线程发,子线程收

多任务TCP服务器

阻塞的在服务的代码段创建子线程,就不影响主线程的进行,就能来一个客户端,并发服务

多任务TCP下载服务器

import os
import threading
import socket
import time
'''
客户端发来文件名,查找传送过去,阻塞的地方是等待发送给每个客户端信息
'''
def server(client_socket,client_addr):
    # while True:
    fil_name = client_socket.recv(1024) #阻塞
    file_name = fil_name.decode('utf-8')
    print(file_name)

    #判断客户端又没有断开连接

    if fil_name:

        if os.path.exists(file_name):
            with open(file_name,'rb') as f:

                #读取了要发送的文件,开始发送
                # print(send_data)
                while True:
                    send_data = f.read(1024)
                    if send_data:
                        client_socket.send(send_data)
                    else:
                        break

        else:
            print('文件不存在:',file_name)
            client_socket.send('null'.encode('utf-8'))
            client_socket.close()
            print('断开了连接',client_addr)
            return
    client_socket.close()
    print('断开了连接',client_addr)
    return
if __name__ == '__main__':
    server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEPORT,True)
    server_socket.bind(('',7789))
    server_socket.listen(128)
    while True:
        client_socket, client_addr= server_socket.accept()
        print('客户端建立了连接',client_addr)
        server_thread = threading.Thread(target=server,args=(client_socket,client_addr))
        server_thread.start()

    server_socket.close()

客户端

import threading
import socket
'''
输入文件名,找到文件
'''
def get_msg(client_socket):
    file_name = input('输入文件名:')
    client_socket.send(file_name.encode('utf-8'))
    print('文件名传输成功')





    buff = []
    while True:
        file_content = client_socket.recv(1024)#阻塞了
        print('接收中。。。')
        if file_content == 'null'.encode('utf-8'):
            print('文件不存在')
            return()
        if file_content:
            buff.append(file_content)
            print('写入一次')
        else:
            break
    data = b''.join(buff)
    with open('拷贝'+file_name,'wb') as f:
        f.write(data)




if __name__ == '__main__':
    dest_ip = '192.168.16.62'
    dest_port = 7789
    client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client_socket.connect((dest_ip,dest_port))
    print('连接成功')
    get_msg(client_socket)
    client_socket.close()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值