pythonnotify
❶ python wait()函数问题
看了你发的函数:
def Wait(self):
self._app.MainLoop()
看名字应该是启动了阻塞循环,去处理app的请求,这个就是需要一直运行的,因为一旦停止了,你的app请求就没发处理了。
如果你需要启动后再执行的别的程序,可以使用多进程,把这个启动放在别的进程里去执行。
如果解决了您的问题请采纳!
如果未解决请继续追问
❷ 请教,ubuntu10.04下,如何卸载python2.7.8
代码:
$ ./configure --prefix=/usr/include
$ make
$ sudo checkinstall
然后,python2.7文件夹出现在/usr/include/bin、/usr/include/liclude和/usr/include/lib中,
输入
代码:
$ python --version
python 2.6.5
但是,却出现如下提示:
[text]
$ sudo apt-get autoremove
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
您也许需要运行“apt-get -f install”来修正上面的错误。
下列软件包有未满足的依赖关系:
command-not-found: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
computer-janitor: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
computer-janitor-gtk: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
gdebi: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
gdebi-core: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
jockey-common: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
lsb-release: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
nvidia-common: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-appindicator: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-apport: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-apt: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-aptdaemon: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-aptdaemon-gtk: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-brlapi: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-cairo: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-crypto: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-cups: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-dbus: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-egenix-mxdatetime: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-egenix-mxtools: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-farsight: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gconf: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gdbm: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-glade2: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gmenu: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gnome2: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gnomeapplet: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gnomecanvas: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gnomekeyring: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gobject: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gst0.10: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gtk2: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gtksourceview2: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-gtkspell: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-imaging: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-indicate: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-launchpad-integration: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-libxml2: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-newt: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-notify: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-openssl: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-pam: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-pkg-resources: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-problem-report: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-pycurl: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-pygoocanvas: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-pyorbit: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-rdflib: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-setuptools: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-simplejson: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-smbc: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-software-properties: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-twisted-bin: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-twisted-core: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-virtkey: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-vte: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-webkit: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-wnck: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-xapian: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
python-zope.interface: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
screen-resolution-extra: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
software-properties-gtk: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
ufw: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
update-manager: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
update-manager-core: 依赖: python (< 2.7) 但是 2.7.8-1 已经安装
❸ Python多线程Condition(条件变量)问题
Python下面的消费者、生产者模式可以用生成器协程来实现,要简单方便的多。
❹ python同时打开几个程序默认运行哪一个
操作系统的作用
隐藏丑陋复杂的硬件接口,提供良好的抽象接口
管理、调度进程,并且将多个进程对硬件的竞争变得有序
2. 多道技术产生背景
针对单核,实现并发
现在的主机一般是多核,那么每个核都会利用多道技术
有 4 个 cpu,运行于 cpu1 的某个程序遇到 io 阻塞,会等到 io 结束再重新调度
会被调度到 4 个 cpu 中的任意一个,具体由操作系统调度算法决定
3. 多道技术空间上的复用:如内存中同时有多道程序
4. 多道技术时间上的复用
复用一个 cpu 的时间片
注意,遇到 io 切,占用 cpu 时间过长也切
核心在于切之前将进程的状态保存下来
这样才能保证下次切换回来时,能基于上次切走的位置继续运行
进程的概念
进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动
进程是操作系统动态执行的基本单元
在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元
进程与程序的区别
程序是指令和数据的有序集合,是一个静态的概念。程序可以作为一种软件资料长期存在,是永久的
进程是程序在处理机上的一次执行过程,它是一个动态的概念。进程是有一定生命期的,是暂时的
5. 注意:同一个程序执行两次,就会在操作系统中出现两个进程。所以可以同时运行一个软件,分别做不同的事情也不会混乱,比如可以打开两个Pycharm做不同的事
6. 进程调度
要想多个进程交替运行,操作系统必须对这些进程进行调度
这个调度也不是随即进行的,而是需要遵循一定的法则
由此就有了进程的调度算法:先来先服务调度算法、短作业优先调度算法、时间片轮转法、多级反馈队列
并行和并发
并行是指在一个时间点上,有多个进程在被 cpu 计算,比如赛跑,两个人都在不停的往前跑
并发是指资源有限的情况下,在一个时间段上,有多个进程在被 cpu 计算,交替轮流使用资源
并行与并发的区别
并行是从微观上,也就是在一个精确的时间片刻,有不同的程序在执行,这就要求必须有多个处理器
并发是从宏观上,在一个时间段上可以看出是同时执行的,比如一个服务器同时处理多个 session
进程的三状态
在程序运行的过程中,由于被操作系统的调度算法控制,程序会进入几个状态
就绪
运行
阻塞
2. 举例说明什么是 argv,什么是阻塞
import sys
print(sys.argv)
# 运行结果:
['G:/course_select/进程的概念.py']
# argv 指参数
# sys.argv 是 Python 解释器在运行的时候传递进来的参数
# 首先在cmd输入以下信息:
python G:/course_select/进程的概念.py
# 打印结果:
['G:/course_select/进程的概念.py']
# 然后在cmd中切换路径到G盘,接着输入 python course_select/进程的概念.py
# 打印结果:
['course_select/进程的概念.py']
# 接着,再在cmd中输入:python course_select/进程的概念.py 123 abc
# 打印结果:
['course_select/进程的概念.py', '123', 'abc']
# 因此,以下程序不能在编辑器里运行,只能在 cmd 里面使用 Python 运行本文件
# 然后要在后面加上 aaa bbb
# 就像上面的 python course_select/进程的概念.py 123 abc 一样
if sys.argv[1] == "aaa" and sys.argv[2] == "bbb":
print("登录成功")
else:
print("登录失败")
exit()
print(666)
# 而如果使用input(),其实就是一种阻塞
3. 进程的三状态图
.png
同步异步
同步:形象的说,一件事的执行必须依赖另一件事的结束,强调的是顺序性
异步: 形象的说,两件事情可以同时进行
注意:同步异步和并行、并发没关系
阻塞:等待,比如 input sleep recv accept recvfrom
非阻塞:不等待,start/terminate 都是非阻塞的
阻塞与非阻塞主要是从程序(线程)等待消息通知时的状态角度来说的
可以分为四类:
同步阻塞
异步阻塞
同步非阻塞
异步非阻塞
start/terminate 都是非阻塞的
进程模块
跟进程相关的基本都在这个模块里:multiprocessing
父进程与子进程的对比分析
父进程,比如运行本文件
子进程,运行 Process(target=func).start()
父进程与子进程数据隔离
主进程等待子进程结束之后再结束
子进程和主进程之间默认是异步的
from multiprocessing import Process
import time
def func():
time.sleep(1)
print(666)
if __name__ == "__main__":
# 开启了一个新的进程,在这个新的进程里执行的 func()
Process(target=func).start()
time.sleep(1)
# 主进程
print(777)
# 777
# 666
# 运行结果仔细观察发现有异步的效果
# 也就是说,主进程和新的进程同时执行
3. 上面的示例中为什么要有 if __name__ == "__main__"?其实这是 windows 操作系统开启子进程的方式问题
4. 继续深入
import time
import os
from multiprocessing import Process
def func():
time.sleep(1)
print(666, os.getpid(), os.getppid())
if __name__ == "__main__":
# 代码执行到这里并不代表开启了子进程
p = Process(target=func)
# 开启了一个子进程,并执行func()
p.start()
time.sleep(1)
print(777, os.getpid(), os.getppid())
# 主进程运行的结果
777 12340 1636
# 子进程运行的结果
666 7604 12340
# 由上面两行结果可以得出:
# 利用 os.getpid() 证明两个进程不一样
# 另外每次运行,os.getpid() 结果都不一样
# 但是,12340 是主进程的 id,7604 是子进程的 id
# 1636 是 Pycharm 的 id,排列特点不变
5. 开启多个相同的子进程示例
import time
import os
from multiprocessing import Process
def func():
time.sleep(3)
print(666, os.getpid(), os.getppid())
if __name__ == "__main__":
for i in range(10):
p = Process(target=func)
p.start()
time.sleep(1)
print(777, os.getpid(), os.getppid())
# 这里需要注意一点:Python 程序一直都是逐行执行
# 但是因为这里设置了时间延迟,因此会先执行主程序的代码
# 运行结果:
777 29006 3833 # 暂停 2s 后再有下面的结果
666 29007 29006
666 29009 29006
666 29008 29006
666 29010 29006
666 29013 29006
666 29011 29006
666 29012 29006
666 29014 29006
666 29016 29006
666 29015 29006
# 观察结果发现主进程只运行了一次
# 然后剩下的全是一个子进程重新运行的结果
# 主进程运行完不会结束,它会等子进程全部运行结束
# 注意变量 p 拿到的是最后一个子进程的 id
6. 开启多个不同的子进程示例
import time
import os
from multiprocessing import Process
def func():
time.sleep(2)
print(666, os.getpid(), os.getppid())
def func2():
print(111)
if __name__ == "__main__":
for i in range(3):
p = Process(target=func)
p.start()
for i in range(2):
p = Process(target=func2)
p.start()
time.sleep(1)
print(777, os.getpid(), os.getppid())
# 运行程序时仔细观察结果显示顺序:
111
111
777 29316 3833
666 29319 29316
666 29317 29316
666 29318 29316
7. 给子进程传参示例
from multiprocessing import Process
def func(name):
print(666, name)
if __name__ == "__main__":
p = Process(target=func,args=(777,)) # 注意是一个元组
p.start()
import time
from multiprocessing import Process
def func(num, name):
time.sleep(1)
print(num, "hello", name)
if __name__ == "__main__":
for i in range(10):
p = Process(target=func, args=(i, "abc"))
p.start()
print("主进程")
# 运行结果:
666 777
主进程
0 hello abc
2 hello abc
1 hello abc
3 hello abc
5 hello abc
4 hello abc
6 hello abc
7 hello abc
8 hello abc
9 hello abc
# 多运行几次,发现子进程并不是完全按顺序运行的
# 比如上面先出结果 2 hello abc,再出结果 1 hello abc
8. 子进程可以有返回值吗:不能有返回值,因为子进程函数中的返回值无法传递给父进程
import time
from multiprocessing import Process
def func():
time.sleep(3)
print("这是子进程,3s后才运行")
if __name__ == "__main__":
Process(target=func).start()
print("主进程")
# 运行结果:
主进程
这是子进程,3s后才运行
# 主进程会默认等待子进程结束之后才结束
# 因为父进程要负责回收子进程占用的操作系统资源
相关资源:Python多进程写入同一文件的方法_python多进程写入同意文件-其它...
文章知识点与官方知识档案匹配
Python入门技能树首页概览
194693 人正在系统学习中
点击阅读全文
打开CSDN,阅读体验更佳
Python多进程(一)进程及进程池_程序员-夏天的博客
print("主进程结束") 通过上述代码我们发现,multiprocessing.Process帮我们创建一个子进程,并且成功运行,但是我们发现,在子进程还没执行完的时候主进程就已经死了,那么这个子进程在主进程结束后就是一个孤儿进程,那么我们可以让主进程等待...
Python多进程之Process、Pool、Lock、Queue、Event、Semaphore、Pipe_大 ...
1. Python创建进程类Process python的multiprocessing模块提供了一个创建进程的类Precess,其创建有以下两种方法: 创建Process类的实例,并指向目标函数和传递参数 自定义一个类并继承Process类,重写__init__()和run()方法 ...
python两个进程同时开启只运行了一个_二十二、 深入Python的进程和线程(上篇)...
“@Author: Runsen”进程(Process)和线程(Thread)都是操作系统中的基本概念,它们之间有一些优劣和差异,那么在Python中如何使用进程和线程?CPU计算机的核心是CPU,它承担了计算机的所有计算任务,CPU就像一个工厂,时刻在运行着,而操作系统管理着计算机,负责任务的调度、资源的分配和管理。进程进程是指在系统中能独立运行并作为资源分配的基本单位,它是由一组机器指令、数据...
继续访问
python启动多个进程_Python多处理:只有一个进程正在运行
由于注释表明您希望使用初始化程序和initargs参数传递featureVector.在Unix类型的系统上,这将导致大量的性能提升(即使selLabel中只有1个项目),因为该值将使用os.fork基本上免费传递给子进程.否则,每次调用foo时,featureVector都将被父进程pickle,通过管道传递并由子进程进行unpickled.这将花费很长时间,并且基本上将序列化所有子进程,因为它...
继续访问
python多进程多线程,多个程序同时运行_陈逸飞_p的博客_pyth...
python 模块应用 开发工具 pycharm 实现方法 多任务的实现可以用进程和线程来实现 进程—> 线程---> 多任务应用 多进程操作 比如下载多个文件, 利用cpu 资源 提高效率 多任务: 同一时间执行多个任务, 比如windows操作系统 执行...
python多进程单例_Python多线程处理实例详解【单进程/多进程】
python — 多线程处理 1、一个进程执行完后,继续下一个进程 root@72132server:~# cd /root/python/multiprocess/ root@72132server:~/python/multiprocess# ls multprocess.py root@72132server:~/python/multiprocess# cat multprocess...
系统编程__2__父子进程的创建和回收
系统编程 这里写的是对于小白来说更多的了解系统编程的文章,有写的不对的地方还恳请各位大佬指出错误,小编一定会多多采纳[手动多谢]。 那么,上一次我们稍微了解了一下关于系统编程的一些主要内容[没有看到的童鞋还请去上一篇文章稍微复习一下噢]。 这节课,我们先来想一想,我们为什么要学系统编程呢?原因很简单,我们要充分的利用CPU的性能,CPU和我们人类不太一样,我们人类大多数情况下,在同一时间,只能完成一件事,而CPU作为无数科学家的心血当然不会这么简单,CPU能够同时进行多个进程,这里的进程我们可以理解成任务,
继续访问
android 10 system/core无法打印log问题
1.关闭重定向 system/core/init/util.cpp --- a/init/util.cpp +++ b/init/util.cpp @@ -454,7 +454,7 @@ static void InitAborter(const char* abort_message) { // SetStdioToDevNull() must be called again in second stage init. void SetStdioToDevNull(char** argv) { ...
继续访问
Python多进程1 一个多进程实例_BBJG_001的博客
下执行,job('主进程step1###')p1=mp.Process(target=job,args=('新进程>>>',))# 创建一个进程# 注意当只有一个参数的时候,一定要在参数后面加一个逗号,因为args需要是一个可以迭代的参量p1.start()# 开始执行新进程# p...
热门推荐 python多进程多线程,多个程序同时运行
python 多线程 多进程同时运行 多任务要求 python 基础语法 python 文件目录操作 python 模块应用 开发工具 pycharm 实现方法 多任务的实现可以用进程和线程来实现 进程—> 线程----> 多任务应用 多进程操作 比如下载多个文件, 利用cpu 资源 提高效率 多任务: 同一时间执行多个任务, 比如windows操作系统 执行方式有两种( 表现形式 ) 并发 在单核cpu中: 在一段时间内交替执行多个任务, 例如单核cpu 处理多任务, 操作系统让各个任务交
继续访问
fork()函数
多进程通信 fork()函数
继续访问
(1/7)Electron教程(一)什么是 Electron,由来、适用场景 和 Electron 的环境搭建(1/7)
最近自己有个小的需求,是做一个能编辑本地特定文本的工具,需要跨平台, Windows 和 macOS,这样,如果用原生开发的话,Windows 就要用c#macOS 就要用swift,学习成本高,并且学完用处也不是很大。我本身是前端开发的,发现了这个electron能满足我的需求,跨平台运行,内部是 js 驱动的,简直就是如鱼得水。顺便把学习的经历写出来,分享需要的人,我会按标题序号渐进式地编写内容。electron。...
继续访问
fork()详解
<一>: fork()函数用来创建新的进程,它的特点是调用一次返回两次( 在原来的进程中返回新进程的 PID(新进程的 PID 肯定不等于 0), 在新进程中返回为 0.) 函数原型:pid_t fork(void); pid_t getpid(); 获取当前进程的 pid 值。 pid_t getppid(); 获取当前进程的父进程 pid 值。 图一 如图一所...
继续访问
fork()函数详解
目录 1.基本了解: 2.fork函数的了解: 3.僵死进程: 1.基本了解: 一个进程,包括代码、数据和分配给进程的资源。fork 函数会新生成一个进程,调用 fork 函数的进程为父进程,新生成的进程为子进程。在父进程中返回子进程的 pid,在子进程中返回 0,失败返回-1。 为什么两个进程的fpid不同呢,这与fork函数的特性有关。fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值: 1)在父进程中,fork返回新创建子进程的进程...
继续访问
Electron在Windows下的环境搭建
Electron作为一种用javascript写桌面程序的开发方式,现在已经被大众接受。下面就介绍如何在windows(>win7)下快速搭建Electron开发环境。 1. nodejs 的安装 从nodejs 下载最新版本的windows安装程序进行安装,我下载的是v6.9.1,安装时一路默认即可,这个安装会把nodejs和npm配置到系统PATH中,这样在命令行的任何位置都可以直接...
继续访问
python多线程pool_Python mutiprocessing多线程池pool操作示例
本文实例讲述了Python mutiprocessing多线程池pool操作。分享给大家供大家参考,具体如下:python — mutiprocessing 多线程 pool脚本代码:root@72132server:~/python/multiprocess# lsmultiprocess_pool.py multprocess.pyroot@72132server:~/python/multi...
继续访问
最新发布 python入门开发学习笔记之守护进程
本节重点 了解守护进程的概念 本节时长需控制在5分钟内 一 守护进程 主进程创建子进程,然后将该进程设置成守护自己的进程,守护进程就好比崇祯皇帝身边的老太监,崇祯皇帝已死老太监就跟着殉葬了。 关于守护进程需要强调两点: 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children 如果我们有两个任务需要并发执行,那么开一个主进程和一个子进程分
继续访问
用python进行多进程编程时,只有主进程可以运行,子进程貌似没有运行是什么原因?
找了半天,原来是这个原因!这是因为multiprocessing模块在交互模式是不支持的,在 cmd 里头输入 python xxx.py 来运行起来,你就可以看到子进程的执行了。
继续访问
linux中fork() 函数详解
fork入门知识 一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。 一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了...
继续访问
Windows版 Node.js 安装详解以及Electron安装
Windows Node.js 安装详解以及Electron安装详解,示例版本:node v10.15.0/npm6.4.1 介绍: 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执...
继续访问
Electron 简介
本教程我们来学习 Electron 的基础知识,下面我们先来学习一下什么是 Electron。 Electron是什么 Electron 是是 GitHub 开发的一个开源框架。它允许使用 Node.js(作为后端)和 Chromium(作为前端)完成桌面 GUI 应用程序的开发。 Electron 可以用于构建具有 HTML、CSS、JavaScript 的跨平台桌面应用程序,它通过将 Chromium 和 node.js 合同一个运行的环境中来实现这一点,应用程序可以打包到 Mac、Windows 和
继续访问
Election的优缺点
优点 原生的接口(菜单、消息提醒、系统托盘等)。 上手难度低。能够使用react、vue等前端框架,能方便地迁移前端组件,构建出漂亮的桌面应用。 方便热更新 调试和测试方便 Electron使用node.js。因此,您可以导入Chrome应用程序中不容易使用的许多模块 Electron文档要好得多,尽管它是一个更年轻的平台 缺点 不适合开发轻量级的应用。即使一个electron的项目框架,也包含chromium内核,打包完接近200G。 相比c++开发的桌面应用,性能远远不如后者。 启动速
继续访问
[electron]终极奥义 五千字教程丢给你
前言 本文包含打包、自动更新、简易API、调试、进程通信等相关知识点,内容较多,可能会引起不适,请酌情查看(手动滑稽)。 electron 简介 electron是由Github开发,是一个用Html、css、JavaScript来构建桌面应用程序的开源库,可以打包为Mac、Windows、Linux系统下的应用。 electron是一个运行时环境,包含Node和Chromium,可以理解成把we...
继续访问
深入理解Java中的wait() 方法
使用场景 当某个线程获取到锁后,发现当前还不满足执行的条件,就可以调用对象锁的wait方法,进入等待状态。 直到某个时刻,外在条件满足了,就可以由其他线程通过调用notify()或者notifyAll()方法,来唤醒此线程。 这篇文章将侧重于讨论wait()方法对于线程状态的影响,以及被唤醒后线程的状态变更。 条件 只有已经获取锁的线程,才可以调用锁的wait方法,否则会抛出异常IllegalMonitorStateException。 比如下面的代码,A获得了锁后,主动调用wait方法释放锁和
继续访问
用Electron开发桌面应用的避坑指南(文末送书)
送一波高质量Web开发图书,送5本书籍,随你挑。抽奖规则见本文最后!抽奖规则见本文最后!抽奖规则见本文最后!如今,Electron 领域发生了重大的变革,Electron 版本更新换代极快...
继续访问
python多进程只有一个进程在执行
python两个进程同时开启只运行了一个。
❺ 深入解析Python中的线程同步方法
深入解析Python中的线程同步方法
同步访问共享资源
在使用线程的时候,一个很重要的问题是要避免多个线程对同一变量或其它资源的访问冲突。一旦你稍不留神,重叠访问、在多个线程中修改(共享资源)等这些操作会导致各种各样的问题;更严重的是,这些问题一般只会在比较极端(比如高并发、生产服务器、甚至在性能更好的硬件设备上)的情况下才会出现。
比如有这样一个情况:需要追踪对一事件处理的次数
counter = 0
def process_item(item):
global counter
... do something with item ...
counter += 1
如果你在多个线程中同时调用这个函数,你会发现counter的值不是那么准确。在大多数情况下它是对的,但有时它会比实际的少几个。
出现这种情况的原因是,计数增加操作实际上分三步执行:
解释器获取counter的当前值计算新值将计算的新值回写counter变量
考虑一下这种情况:在当前线程获取到counter值后,另一个线程抢占到了CPU,然后同样也获取到了counter值,并进一步将counter值重新计算并完成回写;之后时间片重新轮到当前线程(这里仅作标识区分,并非实际当前),此时当前线程获取到counter值还是原来的,完成后续两步操作后counter的值实际只加上1。
另一种常见情况是访问不完整或不一致状态。这类情况主要发生在一个线程正在初始化或更新数据时,另一个进程却尝试读取正在更改的数据。
原子操作
实现对共享变量或其它资源的同步访问最简单的方法是依靠解释器的原子操作。原子操作是在一步完成执行的操作,在这一步中其它线程无法获得该共享资源。
通常情况下,这种同步方法只对那些只由单个核心数据类型组成的共享资源有效,譬如,字符串变量、数字、列表或者字典等。下面是几个线程安全的操作:
读或者替换一个实例属性读或者替换一个全局变量从列表中获取一项元素原位修改一个列表(例如:使用append增加一个列表项)从字典中获取一项元素原位修改一个字典(例如:增加一个字典项、调用clear方法)
注意,上面提到过,对一个变量或者属性进行读操作,然后修改它,最终将其回写不是线程安全的。因为另外一个线程会在这个线程读完却没有修改或回写完成之前更改这个共享变量/属性。
锁
锁是Python的threading模块提供的最基本的同步机制。在任一时刻,一个锁对象可能被一个线程获取,或者不被任何线程获取。如果一个线程尝试去获取一个已经被另一个线程获取到的锁对象,那么这个想要获取锁对象的线程只能暂时终止执行直到锁对象被另一个线程释放掉。
锁通常被用来实现对共享资源的同步访问。为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁,则当前线程需等待其被释放),待资源访问完后,再调用release方法释放锁:
lock = Lock()
lock.acquire() #: will block if lock is already held
... access shared resource
lock.release()
注意,即使在访问共享资源的过程中出错了也应该释放锁,可以用try-finally来达到这一目的:
lock.acquire()
try:
... access shared resource
finally:
lock.release() #: release lock, no matter what
在Python 2.5及以后的版本中,你可以使用with语句。在使用锁的时候,with语句会在进入语句块之前自动的获取到该锁对象,然后在语句块执行完成后自动释放掉锁:
from __future__ import with_statement #: 2.5 only
with lock:
... access shared resource
acquire方法带一个可选的等待标识,它可用于设定当有其它线程占有锁时是否阻塞。如果你将其值设为False,那么acquire方法将不再阻塞,只是如果该锁被占有时它会返回False:
if not lock.acquire(False):
... 锁资源失败
else:
try:
... access shared resource
finally:
lock.release()
你可以使用locked方法来检查一个锁对象是否已被获取,注意不能用该方法来判断调用acquire方法时是否会阻塞,因为在locked方法调用完成到下一条语句(比如acquire)执行之间该锁有可能被其它线程占有。
if not lock.locked():
#: 其它线程可能在下一条语句执行之前占有了该锁
lock.acquire() #: 可能会阻塞
简单锁的缺点
标准的锁对象并不关心当前是哪个线程占有了该锁;如果该锁已经被占有了,那么任何其它尝试获取该锁的线程都会被阻塞,即使是占有锁的这个线程。考虑一下下面这个例子:
lock = threading.Lock()
def get_first_part():
lock.acquire()
try:
... 从共享对象中获取第一部分数据
finally:
lock.release()
return data
def get_second_part():
lock.acquire()
try:
... 从共享对象中获取第二部分数据
finally:
lock.release()
return data
示例中,我们有一个共享资源,有两个分别取这个共享资源第一部分和第二部分的函数。两个访问函数都使用了锁来确保在获取数据时没有其它线程修改对应的共享数据。
现在,如果我们想添加第三个函数来获取两个部分的数据,我们将会陷入泥潭。一个简单的方法是依次调用这两个函数,然后返回结合的结果:
def get_both_parts():
first = get_first_part()
seconde = get_second_part()
return first, second
这里的问题是,如有某个线程在两个函数调用之间修改了共享资源,那么我们最终会得到不一致的数据。最明显的解决方法是在这个函数中也使用lock:
def get_both_parts():
lock.acquire()
try:
first = get_first_part()
seconde = get_second_part()
finally:
lock.release()
return first, second
然而,这是不可行的。里面的两个访问函数将会阻塞,因为外层语句已经占有了该锁。为了解决这个问题,你可以通过使用标记在访问函数中让外层语句释放锁,但这样容易失去控制并导致出错。幸运的是,threading模块包含了一个更加实用的锁实现:re-entrant锁。
Re-Entrant Locks (RLock)
RLock类是简单锁的另一个版本,它的特点在于,同一个锁对象只有在被其它的线程占有时尝试获取才会发生阻塞;而简单锁在同一个线程中同时只能被占有一次。如果当前线程已经占有了某个RLock锁对象,那么当前线程仍能再次获取到该RLock锁对象。
lock = threading.Lock()
lock.acquire()
lock.acquire() #: 这里将会阻塞
lock = threading.RLock()
lock.acquire()
lock.acquire() #: 这里不会发生阻塞
RLock的主要作用是解决嵌套访问共享资源的问题,就像前面描述的示例。要想解决前面示例中的问题,我们只需要将Lock换为RLock对象,这样嵌套调用也会OK.
lock = threading.RLock()
def get_first_part():
... see above
def get_second_part():
... see above
def get_both_parts():
... see above
这样既可以单独访问两部分数据也可以一次访问两部分数据而不会被锁阻塞或者获得不一致的数据。
注意RLock会追踪递归层级,因此记得在acquire后进行release操作。
Semaphores
信号量是一个更高级的锁机制。信号量内部有一个计数器而不像锁对象内部有锁标识,而且只有当占用信号量的线程数超过信号量时线程才阻塞。这允许了多个线程可以同时访问相同的代码区。
semaphore = threading.BoundedSemaphore()
semaphore.acquire() #: counter减小
... 访问共享资源
semaphore.release() #: counter增大
当信号量被获取的时候,计数器减小;当信号量被释放的时候,计数器增大。当获取信号量的时候,如果计数器值为0,则该进程将阻塞。当某一信号量被释放,counter值增加为1时,被阻塞的线程(如果有的话)中会有一个得以继续运行。
信号量通常被用来限制对容量有限的资源的访问,比如一个网络连接或者数据库服务器。在这类场景中,只需要将计数器初始化为最大值,信号量的实现将为你完成剩下的事情。
max_connections = 10
semaphore = threading.BoundedSemaphore(max_connections)
如果你不传任何初始化参数,计数器的值会被初始化为1.
Python的threading模块提供了两种信号量实现。Semaphore类提供了一个无限大小的信号量,你可以调用release任意次来增大计数器的值。为了避免错误出现,最好使用BoundedSemaphore类,这样当你调用release的次数大于acquire次数时程序会出错提醒。
线程同步
锁可以用在线程间的同步上。threading模块包含了一些用于线程间同步的类。
Events
一个事件是一个简单的同步对象,事件表示为一个内部标识(internal flag),线程等待这个标识被其它线程设定,或者自己设定、清除这个标识。
event = threading.Event()
#: 一个客户端线程等待flag被设定
event.wait()
#: 服务端线程设置或者清除flag
event.set()
event.clear()
一旦标识被设定,wait方法就不做任何处理(不会阻塞),当标识被清除时,wait将被阻塞直至其被重新设定。任意数量的线程可能会等待同一个事件。
Conditions
条件是事件对象的高级版本。条件表现为程序中的某种状态改变,线程可以等待给定条件或者条件发生的信号。
下面是一个简单的生产者/消费者实例。首先你需要创建一个条件对象:
#: 表示一个资源的附属项
condition = threading.Condition()
生产者线程在通知消费者线程有新生成资源之前需要获得条件:
#: 生产者线程
... 生产资源项
condition.acquire()
... 将资源项添加到资源中
condition.notify() #: 发出有可用资源的信号
condition.release()
消费者必须获取条件(以及相关联的锁),然后尝试从资源中获取资源项:
#: 消费者线程
condition.acquire()
while True:
...从资源中获取资源项
if item:
break
condition.wait() #: 休眠,直至有新的资源
condition.release()
... 处理资源
wait方法释放了锁,然后将当前线程阻塞,直到有其它线程调用了同一条件对象的notify或者notifyAll方法,然后又重新拿到锁。如果同时有多个线程在等待,那么notify方法只会唤醒其中的一个线程,而notifyAll则会唤醒全部线程。
为了避免在wait方法处阻塞,你可以传入一个超时参数,一个以秒为单位的浮点数。如果设置了超时参数,wait将会在指定时间返回,即使notify没被调用。一旦使用了超时,你必须检查资源来确定发生了什么。
注意,条件对象关联着一个锁,你必须在访问条件之前获取这个锁;同样的,你必须在完成对条件的访问时释放这个锁。在生产代码中,你应该使用try-finally或者with.
可以通过将锁对象作为条件构造函数的参数来让条件关联一个已经存在的锁,这可以实现多个条件公用一个资源:
lock = threading.RLock()
condition_1 = threading.Condition(lock)
condition_2 = threading.Condition(lock)
互斥锁同步
我们先来看一个例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time, threading
# 假定这是你的银行存款:
balance = 0
muxlock = threading.Lock()
def change_it(n):
# 先存后取,结果应该为0:
global balance
balance = balance + n
balance = balance - n
def run_thread(n):
# 循环次数一旦多起来,最后的数字就变成非0
for i in range(100000):
change_it(n)
t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t3 = threading.Thread(target=run_thread, args=(9,))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print balance
结果 :
[/data/web/test_python]$ python multhread_threading.py
0
[/data/web/test_python]$ python multhread_threading.py
61
[/data/web/test_python]$ python multhread_threading.py
0
[/data/web/test_python]$ python multhread_threading.py
24
上面的例子引出了多线程编程的最常见问题:数据共享。当多个线程都修改某一个共享数据的时候,需要进行同步控制。
线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。互斥锁为资源引入一个状态:锁定/非锁定。某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
threading模块中定义了Lock类,可以方便的处理锁定:
#创建锁mutex = threading.Lock()
#锁定mutex.acquire([timeout])
#释放mutex.release()
其中,锁定方法acquire可以有一个超时时间的可选参数timeout。如果设定了timeout,则在超时后通过返回值可以判断是否得到了锁,从而可以进行一些其他的处理。
使用互斥锁实现上面的例子的代码如下:
balance = 0
muxlock = threading.Lock()
def change_it(n):
# 获取锁,确保只有一个线程操作这个数
muxlock.acquire()
global balance
balance = balance + n
balance = balance - n
# 释放锁,给其他被阻塞的线程继续操作
muxlock.release()
def run_thread(n):
for i in range(10000):
change_it(n)
加锁后的结果,就能确保数据正确:
[/data/web/test_python]$ python multhread_threading.py
0
[/data/web/test_python]$ python multhread_threading.py
0
[/data/web/test_python]$ python multhread_threading.py
0
[/data/web/test_python]$ python multhread_threading.py
0
❻ python怎么sendnotifymessage
该函数将指定的消息发送到一个或多个窗口。
此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回。
❼ python生产者消费者问题
这个程序里可能有很多问题。
1.变量传递的问题,这个可能会有问题。
2.condition的用法问题。太复杂了。condition.release少加了一个(),这可能是关键。
3.isEmpty的判断问题。
goods建议用Queue,这样你就省去了condition, 也不用担心isEmpty的逻辑问题了。
如果你用进程模型,则复杂的多。线程是共享同一个内存空间的。这与GIL没有关系。
生产消费者模型经常用于任务分发型程序。 比如爬行器,一个线程或者是进程给URL,其它的下载。结果再合并。
或者是WEB SERVER,一个程序accept, 其它的线程进程只是recv, process,send
❽ python多线程老是报错。大神帮忙看看哈
你好,你具体的代码我没看,但单从报错来看,你的变量名写错了:
你定义的是
condition = threading.Condition()
但你第10行引用的是
conditon
少了一个字母i
❾ python多线程怎样同步
锁机制
�6�9�6�9threading的Lock类,用该类的acquire函数进行加锁,用realease函数进行解锁
import threading
import time
class Num:
def __init__(self):
self.num = 0
self.lock = threading.Lock()
def add(self):
self.lock.acquire()#加锁,锁住相应的资源
self.num += 1
num = self.num
self.lock.release()#解锁,离开该资源
return num
n = Num()
class jdThread(threading.Thread):
def __init__(self,item):
threading.Thread.__init__(self)
self.item = item
def run(self):
time.sleep(2)
value = n.add()#将num加1,并输出原来的数据和+1之后的数据
print(self.item,value)
for item in range(5):
t = jdThread(item)
t.start()
t.join()#使线程一个一个执行
�6�9�6�9当一个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态。每次只有一个线程可以获得锁。如果此时另一个线程试图获得这个锁,该线程就会变为“blocked”状态,称为“同步阻塞”(参见多线程的基本概念)。
�6�9�6�9直到拥有锁的线程调用锁的release()方法释放锁之后,锁进入“unlocked”状态。线程调度程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入运行(running)状态。
信号量
�6�9�6�9信号量也提供acquire方法和release方法,每当调用acquire方法的时候,如果内部计数器大于0,则将其减1,如果内部计数器等于0,则会阻塞该线程,知道有线程调用了release方法将内部计数器更新到大于1位置。
import threading
import time
class Num:
def __init__(self):
self.num = 0
self.sem = threading.Semaphore(value = 3)
#允许最多三个线程同时访问资源
def add(self):
self.sem.acquire()#内部计数器减1
self.num += 1
num = self.num
self.sem.release()#内部计数器加1
return num
n = Num()
class jdThread(threading.Thread):
def __init__(self,item):
threading.Thread.__init__(self)
self.item = item
def run(self):
time.sleep(2)
value = n.add()
print(self.item,value)
for item in range(100):
t = jdThread(item)
t.start()
t.join()
条件判断
�6�9�6�9所谓条件变量,即这种机制是在满足了特定的条件后,线程才可以访问相关的数据。
�6�9�6�9它使用Condition类来完成,由于它也可以像锁机制那样用,所以它也有acquire方法和release方法,而且它还有wait,notify,notifyAll方法。
"""
一个简单的生产消费者模型,通过条件变量的控制产品数量的增减,调用一次生产者产品就是+1,调用一次消费者产品就会-1.
"""
"""
使用 Condition 类来完成,由于它也可以像锁机制那样用,所以它也有 acquire 方法和 release 方法,而且它还有
wait, notify, notifyAll 方法。
"""
import threading
import queue,time,random
class Goods:#产品类
def __init__(self):
self.count = 0
def add(self,num = 1):
self.count += num
def sub(self):
if self.count>=0:
self.count -= 1
def empty(self):
return self.count <= 0
class Procer(threading.Thread):#生产者类
def __init__(self,condition,goods,sleeptime = 1):#sleeptime=1
threading.Thread.__init__(self)
self.cond = condition
self.goods = goods
self.sleeptime = sleeptime
def run(self):
cond = self.cond
goods = self.goods
while True:
cond.acquire()#锁住资源
goods.add()
print("产品数量:",goods.count,"生产者线程")
cond.notifyAll()#唤醒所有等待的线程--》其实就是唤醒消费者进程
cond.release()#解锁资源
time.sleep(self.sleeptime)
class Consumer(threading.Thread):#消费者类
def __init__(self,condition,goods,sleeptime = 2):#sleeptime=2
threading.Thread.__init__(self)
self.cond = condition
self.goods = goods
self.sleeptime = sleeptime
def run(self):
cond = self.cond
goods = self.goods
while True:
time.sleep(self.sleeptime)
cond.acquire()#锁住资源
while goods.empty():#如无产品则让线程等待
cond.wait()
goods.sub()
print("产品数量:",goods.count,"消费者线程")
cond.release()#解锁资源
g = Goods()
c = threading.Condition()
pro = Procer(c,g)
pro.start()
con = Consumer(c,g)
con.start()
同步队列
�6�9�6�9put方法和task_done方法,queue有一个未完成任务数量num,put依次num+1,task依次num-1.任务都完成时任务结束。
import threading
import queue
import time
import random
'''
1.创建一个 Queue.Queue() 的实例,然后使用数据对它进行填充。
2.将经过填充数据的实例传递给线程类,后者是通过继承 threading.Thread 的方式创建的。
3.每次从队列中取出一个项目,并使用该线程中的数据和 run 方法以执行相应的工作。
4.在完成这项工作之后,使用 queue.task_done() 函数向任务已经完成的队列发送一个信号。
5.对队列执行 join 操作,实际上意味着等到队列为空,再退出主程序。
'''
class jdThread(threading.Thread):
def __init__(self,index,queue):
threading.Thread.__init__(self)
self.index = index
self.queue = queue
def run(self):
while True:
time.sleep(1)
item = self.queue.get()
if item is None:
break
print("序号:",self.index,"任务",item,"完成")
self.queue.task_done()#task_done方法使得未完成的任务数量-1
q = queue.Queue(0)
'''
初始化函数接受一个数字来作为该队列的容量,如果传递的是
一个小于等于0的数,那么默认会认为该队列的容量是无限的.
'''
for i in range(2):
jdThread(i,q).start()#两个线程同时完成任务
for i in range(10):
q.put(i)#put方法使得未完成的任务数量+1
❿ Python:进程(threading)
这里是自己写下关于 Python 跟进程相关的 threading 模块的一点笔记,跟有些跟 Linux 调用挺像的,有共通之处。
https://docs.python.org/3/library/threading.html?highlight=threading#thread-objects
直接传入
继承 Thread 重写 run 方法
threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
group 线程组,未实现
start() 线程就绪
join([timeout]) 阻塞其他线程,直到调用这方法的进程结束或时间到达
RuntimeError: cannot join thread before it is started
get/setName(name) 获取/设置线程名。
isAlive() 返回线程是否在运行。
is/setDaemon(bool): 获取/设置是后台线程(默认前台线程(False))。(在start之前设置)
The entire Python program exits when no alive non-daemon threads are left.
没有非后台进程运行,Python 就退出。
主线程执行完毕后,后台线程不管是成功与否,主线程均停止
t.start()
t.join()
start() 后 join() 会顺序执行,失去线程意义
https://docs.python.org/3/library/threading.html?#lock-objects
Lock属于全局,Rlock属于线程(R的意思是可重入,线程用Lock的话会死锁,来看例子)
acquire(blocking=True, timeout=-1) 申请锁,返回申请的结果
release() 释放锁,没返回结果
https://docs.python.org/3/library/threading.html#condition-objects
可以在构造时传入rlock lock实例,不然自己生成一个。
acquire([timeout])/release(): 与lock rlock 相同
wait([timeout]): 调用这个方法将使线程进入等待池,并释放锁。调用方法前线程必须已获得锁定,否则将抛出异常。
notify(): 调用这个方法将从等待池挑选一个线程并通知,收到通知的线程将自动调用acquire()尝试获得锁定(进入锁定池);其他线程仍然在等待池中。调用这个方法不会释放锁定。调用方法前线程必须已获得锁定,否则将抛出异常。
notifyAll(): 调用这个方法将通知等待池中所有的线程,这些线程都将进入锁定池尝试获得锁定。调用这个方法不会释放锁定。使用前线程必须已获得锁定,否则将抛出异常。
threading.Semaphore(value=1)
https://docs.python.org/3/library/threading.html#semaphore-objects
acquire(blocking=True, timeout=None)
资源数大于0,减一并返回,等于0时等待,blocking为False不阻塞进程
返回值是申请结果
release()
资源数加1
https://docs.python.org/3/library/threading.html#event-objects
事件内置了一个初始为False的标志
is_set() 返回内置标志的状态
set() 设为True
clear() 设为False
wait(timeout=None) 阻塞线程并等待,为真时返回。返回值只会在等待超时时为False,其他情况为True
https://docs.python.org/3/library/threading.html#timer-objects
threading.Timer(interval, function, args=None, kwargs=None)
第一个参数是时间间隔,单位是秒,整数或者浮点数,负数不会报错直接执行不等待
可以用cancel() 取消
https://docs.python.org/3/library/threading.html#barrier-objects
threading.Barrier(parties, action=None, timeout=None)
调用的进程数目达到第一个设置的参数就唤醒全部进程
wait(timeout=None)
reset() 重置,等待中的进程收到 BrokenBarrierError 错误