一、线程,可以发现顺序执行比开线程执行时间要短。原因是,一个进程中的多线程处理,由于存在GIL,并且GIL中只能存在一个线程,加上线程又存在切换的问题,所以时间耗得多。想要解决这个问题,是开几个进程,每个进程一个线程,就可以将cpu的多核利用起来,从而节省时间,不过进程对电脑消耗大,不建议开很多进程,因此可以用其他语言,Python不推荐

def add():
sum=0 for i in range(10000000):
sum+=i
print("sum",sum) def mul():
sum2=1
for i in range(1,100000):
sum2*=i
print("sum2",sum2) import threading,time start=time.time() t1=threading.Thread(target=add)
t2=threading.Thread(target=mul) l=[]
l.append(t1)
l.append(t2) # for t in l:
# t.start()
#
#
#
# for t in l:
# t.join() add()
mul() print("cost time %s"%(time.time()-start))

二、关于线程间执行顺序的例子,由于线程是并发的,执行速度很快,如果不sleep的话,可能很快就执行完了,答案是0,但是如果在中间休眠0.001s,会发现结果就不正常了,这是因为在上一个进程还没有计算完的时候,下一个进程就已经取得了数据,解决这个问题,可以用锁,只有锁内的代码执行完后才会执行其他内容。

import threading
import time
def sub():
global num
# num-=1
# print ("ok")
# lock.acquire()
temp=num
time.sleep(0.00001)
num=temp-1
# lock.release() num=100 l=[]
# lock=threading.Lock() for i in range(100):
t=threading.Thread(target=sub)
t.start()
l.append(t) for t in l:
t.join() print(num)

三、队列,put_nowait()相当于put(block=False),q = queue.Queue(3)里面的参数3代表,队列的大小为3个,其余的放不进去,必须等到队列里面有数被提出去了,才可以将数据放进来。

# import threading,time
#
# li=[1,2,3,4]
#
#
# def pri():
# while li:
# a=li[-1]
# print(a)
# time.sleep(1)
# li.remove(a)
# # try:
# # li.remove(a)
# # except Exception as e:
# # print('----',a,e)
#
# t1=threading.Thread(target=pri,args=())
# t1.start()
# t2=threading.Thread(target=pri,args=())
# t2.start() import queue # 线程 队列 q=queue.Queue(3) # FIFO模式 q.put(12)
q.put("hello")
q.put({"name":"yuan"})
q.put_nowait(56)# q.put(block=False) print(q.qsize())
print(q.empty())
print(q.full())
# q.put(34,False) while 1:
data=q.get()
print(data)
print("----------") #先进后出
# import queue # q=queue.LifoQueue()
#
# q.put(12)
# q.put("hello")
# q.put({"name":"yuan"})
#
# while 1:
# data=q.get()
# print(data)
# print("----------") # q=queue.PriorityQueue()
#
# q.put([3,12])
# q.put([2,"hello"])
# q.put([4,{"name":"yuan"}])
#
# while 1:
# data=q.get()
# print(data[1])
# print("----------")

四、线程中setDamon()运用,主线程退出,子线程也退出。

import threading

# def foo():
# print("ok")
#
#
# t1=threading.Thread(target=foo)
# t1.start()
#
# print("ending...") # class MyThread(threading.Thread):
#
# def run(self):
# print("ok")
#
#
# t1=MyThread()
# t1.start()
# print('ending') import threading
from time import ctime,sleep
import time def ListenMusic(name): print ("Begin listening to %s. %s" %(name,ctime()))
sleep(2)# sleep等同于IO操作
print("end listening %s"%ctime()) def RecordBlog(title): print ("Begin recording the %s! %s" %(title,ctime()))
sleep(5)
print('end recording %s'%ctime()) threads = [] t1 = threading.Thread(target=ListenMusic,args=('水手',))
t2 = threading.Thread(target=RecordBlog,args=('python线程',)) threads.append(t1)
threads.append(t2) if __name__ == '__main__':
#t1.setDaemon(True)
t2.setDaemon(True)
for t in threads:
#t.setDaemon(True) #注意:一定在start之前设置
t.start()
# t.join() #t1.join()
#t1.setDaemon(True) #t2.join()########考虑这三种join位置下的结果?
print ("all over %s" %ctime())

五、递归锁,用递归锁,解决死锁问题。

import  threading
import time class MyThread(threading.Thread): def actionA(self): r_lcok.acquire() #count=1
print(self.name,"gotA",time.ctime())
time.sleep(2)
r_lcok.acquire() #count=2 print(self.name, "gotB", time.ctime())
time.sleep(1) r_lcok.release() #count=1
r_lcok.release() #count=0 def actionB(self): r_lcok.acquire()
print(self.name, "gotB", time.ctime())
time.sleep(2) r_lcok.acquire()
print(self.name, "gotA", time.ctime())
time.sleep(1) r_lcok.release()
r_lcok.release() def run(self): self.actionA()
self.actionB() if __name__ == '__main__': # A=threading.Lock()
# B=threading.Lock() r_lcok=threading.RLock()
L=[] for i in range(5):
t=MyThread()
t.start()
L.append(t) for i in L:
i.join() print("ending....")

六、生产者消费者模型

import time,random
import queue,threading q = queue.Queue() def Producer(name):
count = 0
while count <10:
print("making........")
time.sleep(5)
q.put(count)
print('Producer %s has produced %s baozi..' %(name, count))
count +=1
#q.task_done()
q.join()
print("ok......") def Consumer(name):
count = 0
while count <10:
time.sleep(random.randrange(4))
# if not q.empty():
# print("waiting.....")
#q.join()
data = q.get()
print("eating....")
time.sleep(4) q.task_done()
#print(data)
print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))
# else:
# print("-----no baozi anymore----")
count +=1 p1 = threading.Thread(target=Producer, args=('A君',))
c1 = threading.Thread(target=Consumer, args=('B君',))
c2 = threading.Thread(target=Consumer, args=('C君',))
c3 = threading.Thread(target=Consumer, args=('D君',)) p1.start()
c1.start()
c2.start()
c3.start()

七、同步对象,event的使用

import threading,time
class Boss(threading.Thread): def run(self):
print("BOSS:今晚大家都要加班到22:00。")
print(event.isSet())# False
event.set()
time.sleep(5)
print("BOSS:<22:00>可以下班了。")
print(event.isSet())
event.set() class Worker(threading.Thread):
def run(self): event.wait()# 一旦event被设定,等同于pass print("Worker:哎……命苦啊!")
time.sleep(1)
event.clear()
event.wait()
print("Worker:OhYeah!") if __name__=="__main__":
event=threading.Event() threads=[]
for i in range(5):
threads.append(Worker())
threads.append(Boss())
for t in threads:
t.start()
for t in threads:
t.join() print("ending.....")

八、semaphore的使用,限定同时运行线程的个数

import threading,time

class myThread(threading.Thread):
def run(self): if semaphore.acquire():
print(self.name)
time.sleep(3)
semaphore.release() if __name__=="__main__":
semaphore=threading.Semaphore(3) thrs=[]
for i in range(100):
thrs.append(myThread())
for t in thrs:
t.start()

九、进程调用

# from multiprocessing import Process
# import time
#
#
# def f(name):
# time.sleep(1)
# print('hello', name,time.ctime())
#
# if __name__ == '__main__':
# p_list=[]
# for i in range(3):
#
# p = Process(target=f, args=('alvin',))
# p_list.append(p)
# p.start()
#
# for i in p_list:
# i.join()
# print('end') from multiprocessing import Process
import time # class MyProcess(Process):
#
# # def __init__(self):
# # super(MyProcess, self).__init__()
# # #self.name = name
#
# def run(self):
# time.sleep(1)
# print ('hello', self.name,time.ctime())
#
#
# if __name__ == '__main__':
# p_list=[]
#
#
# for i in range(3):
# p = MyProcess()
# p.daemon=True
# p.start()
# p_list.append(p)
#
# # for p in p_list:
# # p.join()
#
# print('end') from multiprocessing import Process
import os
import time def info(title):
print("title:", title)
print('parent process:', os.getppid())
print('process id:', os.getpid()) def f(name): info('function f')
print('hello', name) if __name__ == '__main__': info('main process line') time.sleep(1)
print("------------------")
p = Process(target=info, args=('yuan',))
p.start()
p.join()

笔记:

1.同步锁
2.死锁 递归锁
3.信号量和同步对象(了解)
4.队列------生产者消费者模型
5.进程

并发 & 并行
并发:是指系统具有处理多个任务(动作)的能力
并行:是指系统具有同时处理多个任务(动作)的能力
并行是并发的一个子集
几个线程是并发,因为有GIL,所以只能允许一个线程运行,是并发
几个进程是并行,可以解决线程不能同时运行的问题。可以几个CPU共同运行

同步 与 异步
同步:当进程执行到一个IO(等待外部数据)的时候,-----等:同步
异步: -----不等:异步
打电话是同步,发短信是异步

问题:多核没利用上?
GIL:Global_interpreter_lock全局解释锁
因为有GIL,所以同一时刻只有一个线程被CPU执行

任务:IO密集型 计算密集型

对于IO密集型的任务:python的多线程是有意义的
可以采用多进程+携程
对于计算密集型的任务:python的多线程就不推荐,python就不适用了,可以用其他语言。

信号量用来控制线程并发数的。

python之网络编程--锁、信号量、线程、队列的更多相关文章

  1. python 并发编程 锁 / 信号量 / 事件 / 队列(进程间通信(IPC)) /生产者消费者模式

    (1)锁:进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 虽然使用加锁的形式实现了 ...

  2. python之网络编程

    本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和写记录锁.信号量) 共享内存(匿名的和具名的) 远程过程调用 ...

  3. python基础网络编程--转

    python之网络编程 本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和写记录锁.信号量) 共享内存(匿名的 ...

  4. Python的网络编程--思维导图

    Python的网络编程--思维导图

  5. Python高级网络编程系列之第一篇

    在上一篇中我们简单的说了一下Python中网络编程的基础知识(相关API就不解释了),其中还有什么细节的知识点没有进行说明,如什么是TCP/IP协议有几种状态,什么是TCP三次握手,什么是TCP四次握 ...

  6. python 基础网络编程2

    python 基础网络编程2 前一篇讲了socketserver.py中BaseServer类, 下面介绍下TCPServer和UDPServer class TCPServer(BaseServer ...

  7. python 基础网络编程1

    python 基础网络编程1 Source code: Lib/socketserver.py lib的主目录下有一个sockserver.py文件, 里面是python基本的网络编程模型 共有一个b ...

  8. 图解Python 【第八篇】:网络编程-进程、线程和协程

    本节内容一览图: 本章内容: 同步和异步 线程(线程锁.threading.Event.queue 队列.生产者消费者模型.自定义线程池) 进程(数据共享.进程池) 协程 一.同步和异步 你叫我去吃饭 ...

  9. python中网络编程之线程

    网络编程之线程 什么是线程? 程序的执行线路.每个进程默认有一条线程.线程包含了程序的具体步骤. 多线程就是一个进程中有除主线程(默认线程)外还有多个线程. 线程与进程的关系(进程包含线程,而线程依赖 ...

随机推荐

  1. Android常用的技术框架与博客社区

    技术框架 图片加载 Glide Fresco Volley Picasso Universal Image Loader 网络请求 okhttp retrofit Volley android-asy ...

  2. drf图片字段序列化完整路径

    一.需求 前端需要它想要的数据格式: 原有的数据格式: 二.定制化: 1.可以嵌套序列化pol_type,lit_des,area_detail,但结构如下: class ChrDetailSeria ...

  3. Prism框架研究(三)

    这一篇主要用来介绍一下基于Prism Library中的核心服务以及如何配置Container,还有一个重要的部分是如何管理各个组件之间的依赖性,下面就这些内容来做一一的介绍. 1 Prism中的核心 ...

  4. 老男孩python学习自修【第二天】字符串用法

    实时处理增量日志最佳实践 主要使用f.seek()和f.tell()实现 字符串处理函数: s.find(substr, start, end) 查找子字符串,找不到则返回-1,找到则返回对应的索引 ...

  5. loadrunner -vuser

    在每个负载生成器上,安装 remote agent dispatcher(process) 和 loadrunner agent 控制器指示remote agent dispatcher 在load ...

  6. 学习 Spring (十二) AOP 基本概念及特点

    Spring入门篇 学习笔记 AOP: Aspect Oriented Programming, 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 主要功能是:日志记录.性能统计.安全控 ...

  7. webpack 配置 publicPath的理解

    在学习webpack的时候,配置文件中有一个publicPath属性,一直不是很明白它到底是怎么用,也查了很多资料,得到最多的说法是当打包的时候,webpack会在静态文件路径前面添加publicPa ...

  8. React 学习(五) ---- 条件和列表渲染

    条件渲染 React中的条件渲染和我们平常写的js 代码一样,都是用的if else, 只不过在if else 中它的返回值是jsx, 根据不同的条件渲染不同的UI. 先写两个组件 //登录的用户显示 ...

  9. hdu-4763(kmp+拓展kmp)

    题意:给你一个串,问你满足最大字串既是前后缀,也在字符串除去前后缀的位置中出现过: 思路:我用的是拓展kmp求的前后缀,只用kmp也能解,在字符串2/3的位置后开始遍历,如果用一个maxx保存前2/3 ...

  10. Android与H5交互 原理与对比

    原文:  https://www.jianshu.com/p/345f4d8a5cfa 1.Android调用JS的方法有2种: (1)通过WebView的loadUrl() // 调用js中的函数: ...