线程

线程和进程一样是抽象出来的,做个比喻,进程好比一个造车的车间,而线程就是里面的流水线,有造车轱辘的,还有车架的等等

进程属于一个资源单位,而线程是cup上的执行单位

 

多线程的概念:

是一个进程中的多个线程,注意是一个进程,多个线程享有一个进程的地址空间,共享进程内的资源。

线程的创建开销小:

from threading import Thread
import os
import time


def work():
    print('%s is working'%os.getpid())
    time.sleep(2)
    print('%s is ending'%os.getpid())
if __name__ == '__main__':
    t = Thread(target=work,)
    t.start()
    print('主 %s' % os.getpid())

运行结果:
7604 is working
主 7604
7604 is ending

创建开销小

从结果中可以看出 线程的pid和进程的pid是一样的***

线程与进程的区别

       1 开在一个进程里的多线程的内存空间是一样的,都是主进程的内存空间,而开辟一个新 的进程则是重新开辟一个空间地址。

  2 多线程可以共享一个进程内的资源,而进程之间的资源是隔离的。

  3 新的线程开销小,至于要在原来的进程基础上开辟一条线程;进程的开销大,需要开辟一个新的空间。

开启线程的两种方法

from threading import Thread
import os



def work():
    print('%s is working' % os.getpid())
if __name__ == '__main__':
    t = Thread(target=work,)
    t.start()
    print('主 %s' % os.getpid())
常用的方法
from threading import Thread
import os

class Work(Thread):
    def __init__(self,name):
        super(Work, self).__init__()
        self.name = name

    def run(self):
        print('%s is running %s'%(os.getpid(),self.name))
if __name__ == '__main__':
    t = Work('haidong')
    t.start()
    print('主 %s' % os.getpid())
要知道的,但不常用

 

 线程中主要的方法:守护线程,jion

from threading import Thread
import os
import time


def work():
    print('%s is working' % os.getpid())
    time.sleep(2)
    print('%s is ending' % os.getpid())
if __name__ == '__main__':
    t = Thread(target=work,)
    # t.daemon = True
    t.start()
    print('主 %s' % os.getpid())
   
守护线程
*****守护线程什么时候被回收呢? 主线程运行完了,进程就会结束,所以主线程要等到所有的非守护线程都运行完了才结束,这时回收守护线程。
******守护进程什么时候被回收呢? ok! 在主进程的代码执行完了, 守护进程就会被回收!
from threading import Thread
import os
import time


def work():
    print('%s is working' % os.getpid())
    time.sleep(2)
    print('%s is ending' % os.getpid())
if __name__ == '__main__':
    t = Thread(target=work,)
    t.start()
    t.join() # 主线程会等到子线程运行完在运行
    print('主 %s' % os.getpid())
join

线程中不常有的方法:
Thread实例对象的方法
  # isAlive(): 返回线程是否活动的。
  # getName(): 返回线程名。
  # setName(): 设置线程名。

threading模块提供的一些方法:
  # threading.currentThread(): 返回当前的线程变量。
  # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

  

线程练习:
基于线程的套接字练习
import socket
from threading import Thread

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 参数:网络网络协议, SOCK_STREAM tcp协议
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(('127.0.0.1', 8081))
phone.listen(5)  # 参数, 能挂起几个链接数



def talk(conn):
    while 1: # 通信循环
        try:
            ret = conn.recv(1024)
            if not ret: break  # 对于linux 系统的异常处理
            conn.send(ret.upper())
        except Exception:
            break
    conn.close()

if __name__ == '__main__':

    while 1: # 链接循环
        conn, client_addr = phone.accept() # 元祖,conn 代表链接, client_addr接收到一个IP地址和接口
        print(client_addr)
        p = Thread(target=talk,args=(conn,))
        p.start()

phone.close()
服务端

import socket

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

phone.connect(('127.0.0.1', 8081))

while 1:
    cmd = input('>>: ').strip()
    if not cmd: continue
    phone.send(cmd.encode('utf_8'))
    ret = phone.recv(1024)
    print(ret.decode('utf-8'))


phone.close()
客户端

 

模拟文本编辑器:简单的三种要求,写,改,存
from threading import Thread
import json
l = []
l1 =[]
def xie():
    while 1:
        value = input('>>>: ')
        if not value: continue
        l.append(value)


def geshihua():
    while 1:
        if l:
            value = l.pop()
            l1.append(value.upper())

def baocun():
    while 1:
        if l1:
            with open('db.txt', 'a') as f:
                value = l1.pop()
                f.write('%s\n' % value)
                f.flush()

if __name__ == '__main__':
    t1 = Thread(target=xie)
    t2 = Thread(target=geshihua)
    t3 = Thread(target=baocun)
    t1.start()
    t2.start()
    t3.start()
View Code

 

全局解释器锁:这是个什么东西呢?英文:Global Interpreter Lock 简写:GIL
他是用来干什么的呢?由于python的内存机制,还有为了保护cpython内的数据安全,还有对于多线程对于cpython的竞争变得有序化,给cpython加的一把锁。
当我们要执行python内的代码,修改变量时,就要向cPython请求权限,当多个代码都要进行时,锁的作用就起到了,自己用脚后跟想也能想明白把,要是都去执行cPython内的执行代码,肯定会乱对吧!!






 

posted @ 2017-08-28 19:07  Python界-黄药师  阅读(226)  评论(0)    收藏  举报