python高级学习笔记Day01-- Ubuntu安装pycharm,多任务,多进程,多线程,TCP服务端客户端的开发

操作系统:向下控制硬件,向上支持软件运行

在Ubuntu系统上安装Pycharm

下载地址:Download PyCharm: Python IDE for Professional Developers by JetBrains

解压安装包:

切换到里面的bin目录,执行./pycharm.sh打开软件

多任务

多任务充分利用CPU资源,同时执行提高效率

并发:一段时间内交替执行多个任务(单核CPU处理多任务时)

并行:同时执行多个任务(多核CPU处理多任务)

进程:是操作系统进行资源分配和调度运行的最小单位

主进程:程序运行默认创建的进程

子进程:程序运行后创建的进程

进程的创建

导入进程包:import multiprocessing

通过进程类创建进程对象:进程对象=mutiprocessing.Process(target=任务名)

target参数指函数名,方法名。 name进程名一般不设置。group:进程组目前只能使用None

启动进程执行任务:进程对象.start()

代码如下:

import multiprocessing
import time


def coding():
    for i in range(3):
        print("Coding....")
        time.sleep(0.2)


def music():
    for i in range(3):
        print("music...")
        time.sleep(0.2)


if __name__ == '__main__':
    coding_process = multiprocessing.Process(target=coding())
    music_process = multiprocessing.Process(target=music())
    coding_process.start()
    music_process.start()

进程执行带有参数的任务
python高级学习笔记Day01-- Ubuntu安装pycharm,多任务,多进程,多线程,TCP服务端客户端的开发_第1张图片

args传参时注意顺序一致,kwargs注意key与形参名相同

 代码:

import multiprocessing
import time


def coding(num):
    for i in range(num,name):

        print(name)
        print("Coding....")
        time.sleep(0.2)


def music(count,name):
    for i in range(3):

        print(name)
        print("music...")
        time.sleep(count)


if __name__ == '__main__':
    coding_process = multiprocessing.Process(target=coding, args=(4,"传智播客"))
    music_process = multiprocessing.Process(target=music, kwargs={"count": 3,"name":"gyq"})
    coding_process.start()
    music_process.start()


获取进程编号

引入os模块,getpid(),getppid()方法

import multiprocessing
import os


def work():
    print("workid>>>%d" % os.getpid())
    print("workpid>>>%d" % os.getppid())


if __name__ == '__main__':

    print("pprocessid>>>%d" % os.getpid())
    work_process = multiprocessing.Process(target=work)
    work_process.start()

进程间的全局变量是不共享的

实际上是创建一个子进程就是把主进程资源进行拷贝产生了一个新的进程,两者相互独立

import multiprocessing

my_list = list()


def write():
    for i in range(3):
        my_list.append(i)
        print("add:", i)


def read():
    print(my_list)


if __name__ == '__main__':
    write_process = multiprocessing.Process(target=write)
    read_process = multiprocessing.Process(target=read)
    write_process.start()
    read_process.start()
 

主进程会等待所有子进程执行结束在结束

import multiprocessing
import time


def work():
    for i in range(10):
        print("working..")
        time.sleep(0.2)


if __name__ == '__main__':
    work_process = multiprocessing.Process(target=work)
    work_process.start()
    time.sleep(1)
    print("mainprocess over")

会打印主进程结束但是没有完全结束,哈哈~

主进程结束子进程也关闭的两种方法

1.设置为守护子进程,主进程结束子进程立马结束

2.手动结束

python高级学习笔记Day01-- Ubuntu安装pycharm,多任务,多进程,多线程,TCP服务端客户端的开发_第2张图片

 线程

实现多任务的一个方法

进程一旦创建就会分配一定资源,像是两个人聊qq要打开两个qq软件一样

线程是程序执行的最小单位,进程只负责分配资源,而利用这些资源执行程序的是线程,也就是说进程是线程的容器,线程和与它同属一个进程的其他线程共享进程所拥有的全部资源,像是qq的两个聊天窗口。

在进程中默认有一个线程执行程序,称为主线程

线程的创建

和进程类似

执行带参数的任务的方法与进程相同

import time
import threading


def coding():
    for i in range(3):
        print("coding...")
        time.sleep(0.2)


def music():
    for i in range(3):
        print("music..")
        time.sleep(0.2)


if __name__ == '__main__':
    coding_thread = threading.Thread(target=coding)
    music_thread = threading.Thread(target=music)
    coding_thread.start()
    music_thread.start()

主线程会等待所有子线程执行结束后主线在结束,设置守护子线程与进程方式相同

线程的执行顺序

是无序的,由CPU调度

import threading


def get_info():
    current_thread = threading.current_thread()
    print(current_thread)


if __name__ == '__main__':
    for i in range(10):
        sub_thread = threading.Thread(target=get_info)
        sub_thread.start()

线程之间共享全局变量

import threading
import time

my_list = []


def write():
    for i in range(3):
        print("add:", i)
        my_list.append(i)
    print("write:", my_list)


def read():
    print("read:", my_list)


if __name__ == '__main__':
    write_thread = threading.Thread(target=write)
    read_thread = threading.Thread(target=read)
    write_thread.start()
    time.sleep(1)
    read_thread.start()

线程间资源竞争问题

import threading
import time

g_num=0

def add1():
    for i in range(100000):
        global g_num
        g_num+=1
    print("g_num:", g_num)


def add2():
    for i in range(100000):
        global g_num
        g_num+=1
    print("g_num2:", g_num)


if __name__ == '__main__':
    add1_thread = threading.Thread(target=add1)
    add2_thread = threading.Thread(target=add2)
    add1_thread.start()
    add2_thread.start()


共享全局变量出错解决方法

实现线程同步:

互斥锁:对共享数据进行锁定,保证同一时刻只有一个线程操作

创建互斥锁和上锁,解锁

python高级学习笔记Day01-- Ubuntu安装pycharm,多任务,多进程,多线程,TCP服务端客户端的开发_第3张图片

死锁 

不释放锁就会死锁,别的线程无法访问数据,卡死    记得释放锁

进程和线程的对比

线程依附与进程

一个进程默认提供一条线程,进程可以创建多个线程

区别:

进程之间不共享全局变量

线程之间共享全局变量,但要注意资源竞争的问题

创建进程的资源开销比创建线程的资源开销要大

进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位

线程不能独自运行

进程优缺点

优点:可以使用多核

缺点:资源开销大

线程优缺点

优点:资源开销小

缺点:不能使用多核

网络的概念

实现资源共享和信息传递的虚拟平台

网络编程:编写基于网络通信的软件和程序

端口号

每个网络软件都有一个端口,端口有其对应端口号

端口号的分类

知名端口号:0到1023,一般固定分配给一些服务,比如21端口分配给FTP服务,25端口是SMTP

服务,80端口分给HTTP服务。

动态端口号:1024到65535,如果没有设置就会随机生成一个,使用完后释放

socket介绍

简称套接字,是程序间进行网络通讯的工具

TCP介绍

 Transmission Control Protocol传输控制协议,面向连接的,可靠的,基于字节流的传输层协议。

面向连接:通信双方必须先建立好连接才能进行数据的传输,双方都会为此连接分配必要资源来记录连接的状态和信息,数据传输完成后,双方必须断开连接,以释放系统资源。

可靠:

        采用发送应答机制,发送后得到应答才认为发送成功

        超时重传:发送一个报文后启动定时器,指定时间内没有得到应答就会重新发送这个报文段

        错误校验:TCP用一个校验和函数来校验数据是否有误,再发送和接收时都要计算校验和

        流量控制和拥塞控制:流量控制用来避免发送端发送过而导致对方来不及接收

过程:创建连接,传输数据,关闭连接

python3编码转换

网络传输以二进制进行传输

encode,decode函数(encoding='utf-8')

TCP客户端程序开发流程

网络应用程序分为客户端和服务端,主动发起建立连接的是客户端

流程:

        创建客户端套接字对象

        和服务端套接字建立连接

        发送数据

        接收数据

        关闭客户端套接字

案例:

import socket

if __name__ == '__main__':
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # AF_INET:ipv4,SOCK_STREAM:TCP
    tcp_client_socket.connect(("111.111.111.111", 8080))
    # tuple("ipaddress",port)
    tcp_client_socket.send('are you ok?'.encode(encoding='utf-8'))
    recv_data = tcp_client_socket.recv(1024)
    print(recv_data.decode())
    tcp_client_socket.close()

服务端开发流程

流程:

        创建服务气短套接字对象

        绑定IP地址和端口号

        设置监听

        等待接受客户端请求

        接收数据

        发送数据

        关闭套接字对象

代码:

import socket

if __name__ == '__main__':
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_server_socket.bind(('192.168.199.131', 8888))
    # ''=localhost
    tcp_server_socket.listen(128)  # 128 means max wait num      只接收
    conn_socket, ip_port = tcp_server_socket.accept()#返回一个用以和客户端通讯的socket和客户端地址
    print('address', ip_port)
    recv_data = conn_socket.recv(1024)
    print("getinformation:", recv_data.decode())
    conn_socket.send("get it already!".encode())
    conn_socket.close()
    tcp_server_socket.close()
运行客户端时服务器端输出

客户端输出

python高级学习笔记Day01-- Ubuntu安装pycharm,多任务,多进程,多线程,TCP服务端客户端的开发_第4张图片

 案例:多任务版TCP服务端程序开发

加一个while True即可完成多个客户端与其通信

python高级学习笔记Day01-- Ubuntu安装pycharm,多任务,多进程,多线程,TCP服务端客户端的开发_第5张图片

用线程真正的同时服务于客户端:

import socket
import threading


def handle_client(conn_socket):
    recv_data = conn_socket.recv(1024)
    print("getinformation:", recv_data.decode())
    conn_socket.send("get it already!".encode())
    conn_socket.close()


if __name__ == '__main__':
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_server_socket.bind(('192.168.199.131', 8888))
    # ''=localhost
    tcp_server_socket.listen(128)  # 128 means max wait num
    while True:
        conn_socket, ip_port = tcp_server_socket.accept()
        print('address', ip_port)
        sub_thread = threading.Thread(target=handle_client, args=(conn_socket,))
        sub_thread.start()
    tcp_server_socket.close()


搭建python自带的静态Web服务器

cd 到包含静态资源的static文件夹

你可能感兴趣的:(Python高级,python,开发语言,后端)