也许我遗漏了一些明显的东西(现在是星期五),但是有什么办法可以做到与os.fork()
greenlet上的等效吗?我并不一定要分担该过程,而是要使用greenlet并运行一组代码,然后运行另一组代码,但要使用独立的范围(如os.fork()
)。
有什么主意还是应该睡一下?
我现在已经阅读了几个小时,我可以完全弄清楚python多线程如何比单个线程更快.
这个问题真的源于GIL.如果有GIL,并且任何时候只有一个线程真正运行,那么多线程如何比单个线程更快?
我读到了GIL发布的一些操作(比如写入文件).是什么让多线程更快?
关于greenlets.这些如何帮助并发?到目前为止,我看到的所有目的都是在功能和较简单的屈服功能之间轻松切换.
编辑:世界上像Tornado这样的服务器如何处理成千上万的同时连接?
我正在学习Gevent,但无法获得greenlet中调用的函数返回的值.以下代码:
import gevent.monkey
gevent.monkey.patch_socket()
import gevent
from gevent import Greenlet
import urllib2
import simplejson as json
def fetch(pid):
response = urllib2.urlopen('http://time.jsontest.com')
result = response.read()
json_result = json.loads(result)
datetime = json_result['time']
print('Process %s: %s' % (pid, datetime))
return json_result['time']
def synchronous():
for i in range(1,10):
fetch(i)
def asynchronous():
threads = [Greenlet.spawn(fetch, i) for i in range(10)]
result = gevent.joinall(threads)
print [Greenlet.value(thread) for thread in threads]
print('Synchronous:')
synchronous()
print('Asynchronous:')
asynchronous()
Run Code Online (Sandbox Code Playgroud)
给我错误:
print [Greenlet.value(thread) for thread in threads]
AttributeError: type object 'Greenlet' has …
Run Code Online (Sandbox Code Playgroud) 以下代码(取自此处: https: //bitbucket.org/denis/gevent/src/6c710e8ae58b/examples/wsgiserver_ssl.py)实现了一个极快的greenlet驱动的wsgi网络服务器:
#!/usr/bin/python
"""Secure WSGI server example based on gevent.pywsgi"""
from gevent import pywsgi
def hello_world(env, start_response):
if env['PATH_INFO'] == '/':
start_response('200 OK', [('Content-Type', 'text/html')])
return ["<b>hello world</b>"]
else:
start_response('404 Not Found', [('Content-Type', 'text/html')])
return ['<h1>Not Found</h1>']
print 'Serving on https://127.0.0.1:8443'
server = pywsgi.WSGIServer(('0.0.0.0', 8443), hello_world, keyfile='server.key', certfile='server.crt')
# to start the server asynchronously, call server.start()
# we use blocking serve_forever() here because we have no other jobs
server.serve_forever()
Run Code Online (Sandbox Code Playgroud)
然而,这仅在一个核心上运行。您将如何修改它以利用多个进程?不是寻找涉及gunicorn的答案,而是寻找更简单的东西。
暗示
这是使用 gevent 和多处理的代码示例,但我仍然不知道如何使用 WSGI 使其工作(取自https://gist.github.com/1169975): …
码:
import gevent
import time
def func(a, t):
time.sleep(t)
print "got here", a
gevent.spawn(func, 'a', 4)
gevent.spawn(func, 'b', 0).join()
time.sleep(3)
print "exit"
Run Code Online (Sandbox Code Playgroud)
输出:
got here a
got here b
exit
Run Code Online (Sandbox Code Playgroud)
期望:
我从不加入第一个greenlet,所以我希望它永远不会执行; 或者,如果长睡眠(),它应该在第二个greenlet之后完成.
语境:
我希望能够启动一个"一次性"greenlet填充缓存,我永远不会加入,我永远不想阻止等待结果.
我理解阻塞代码在事件循环(即NodeJS)时是一种罪恶,但是对于greenlets(我认为是绿色线程)怎么样?运行代码调用阻塞函数是否存在问题?
我是一名 Java 开发人员并开始学习 Python 语言,最近我遇到了使用异步 greenlets 的 Python Gevent 库。有人可以解释我,如何使用 Gevent 在 Python 中同步、死锁、活锁工作/避免。
我有比这更多的代码,所以我把它修改为看似相关的东西.根据记录的示例,我有一个用于ZeroRPC的python类:
import zerorpc, sys, signal
class MyClass:
pass
zpc = 0
if __name == '__main__':
zpc = zerorpc.Server(MyClass)
zpc.bind('ipc://./mysocket.sock')
zpc.run()
print("zpc stopped"); sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)
python脚本从我的Node.js服务器生成为ChildProcess,它监听stdout和stderr.当客户端连接超时或服务器关闭时,我在ChildProcess上调用kill(),它向它发送SIGTERM.
仅使用上面的代码,'zpc stopped'永远不会在Node.js回调中捕获,这表明ZeroRPC服务器在其运行循环中的某处被杀死.此外,套接字文件仍然存在,表明服务器也没有关闭套接字.所以我想在捕获SIGTERM后我会在服务器上调用stop()或close():
def sig_handle (signal, frame):
global zpc
print("SIGTERM received.") # <-- this does occur
zpc.stop() # <-- Exception thrown here and at run()
sys.exit(0)
signal.signal(signal.SIGTERM, sig_handle)
Run Code Online (Sandbox Code Playgroud)
Node.js通过其stderr回调获取异常:
Gateway Error: File "/usr/lib/python2.6/site-packages/zerorpc/core.py", line 178, in stop
Gateway Error: self._acceptor_task.kill()
File "/usr/lib64/python2.6/site-packages/gevent/greenlet.py", line 235, in kill
Gateway Error: waiter.get()
File "/usr/lib64/python2.6/site-packages/gevent/hub.py", line 568, in get
Gateway Error: …
Run Code Online (Sandbox Code Playgroud) 我有两个函数从两个不同的连接接收数据,我应该在从其中之一获得结果后关闭这两个连接。
def first():
gevent.sleep(randint(1, 100)) # i don't know how much time it will work
return 'foo'
def second():
gevent.sleep(randint(1, 100)) # i don't know how much time it will work
return 'bar'
Run Code Online (Sandbox Code Playgroud)
然后我生成每个函数:
lst = [gevent.spawn(first), gevent.spawn(second)]
Run Code Online (Sandbox Code Playgroud)
gevent.joinall
阻塞当前的 greenlet,直到两个 greenlet 都lst
准备好。
gevent.joinall(lst) # wait much time
print lst[0].get(block=False) # -> 'foo'
print lst[1].get(block=False) # -> 'bar'
Run Code Online (Sandbox Code Playgroud)
我想等到第一个或第二个 greenlet 准备好:
i_want_such_function(lst) # returns after few seconds
print lst[0].get(block=False) # -> 'foo' because this greenlet is ready
print …
Run Code Online (Sandbox Code Playgroud) 当我使用标准logging
包从greenlet中打印出日志语句时,我得到的文本如下所示:
2014-02-06 22:38:43,428 [INFO] (11396-Dummy-2) event_listener: About to block
Run Code Online (Sandbox Code Playgroud)
我指的是这个11396-Dummy-2
部分.我希望它能说出像'Main'或'Listener 1'这样的东西.这可能吗?从当前的文档中我没有看到任何API这样做.
一切都很好?我使用docker build时遇到问题.此应用程序已安装在其他2台计算机上,但每次发生此错误时.有谁知道我应该做些什么来解决它.我有一个Windows 10,我正在使用Docker Toolbox.
我在网站上尝试了这个答案,没有成功:
我按照docker自己的网站上的对接教程:
https://docs.docker.com/compose/django/#define-the-project-components
Dockerfile
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
RUN pip3 install virtualenv
RUN virtualenv /code
ADD requirements.txt /code/
RUN python -m pip install -r requirements.txt --no-cache-dir
ADD . /code/
Run Code Online (Sandbox Code Playgroud)
错误日志:
PS C:\Users\ThinkPad\Documents\ChatBot> docker build -t backend .
Sending build context to Docker daemon 209.5MB
Step 1/9 : FROM python:3
---> ce54ff8f2af6
Step 2/9 : ENV PYTHONUNBUFFERED 1
---> Using cache
---> 5cefadc9e069
Step 3/9 : RUN mkdir /code
---> …
Run Code Online (Sandbox Code Playgroud) 我有以下Python代码:
>>> import gevent
>>> from gevent import monkey; monkey.patch_all()
>>>
>>> def fooFn(k):
... return 'gevent_'+k
...
>>> threads = []
>>> threads.append(gevent.spawn(fooFn,'0'))
>>> threads.append(gevent.spawn(fooFn,'1'))
>>>
>>> gevent.joinall([threads[1]])
>>>
>>> print threads[1].value
gevent_1
>>> print threads[0].value
gevent_0
>>>
Run Code Online (Sandbox Code Playgroud)
如上所示,threads[0].value
从中获得了适当的值fooFn
。这意味着threads[0]
greenlet已执行。
当我仅将threads[1]
greenlet 传递给时,为什么会发生这种情况gevent.joinall
?
我如何确保仅执行实际传递给的那些greenlet gevent.joinall
?
我在基于gevent的框架上将pymongo驱动程序与mongodb一起使用。我不了解工作池连接。我在每个请求上创建一个新的连接实例:
connection = MongoClient(host='localhost', port=27017, use_greenlets=True)
Run Code Online (Sandbox Code Playgroud)
实际是从一个池中取得连接?
现在,如果我进行连接:
connection = MongoClient(host='localhost', port=27017)
Run Code Online (Sandbox Code Playgroud)
这是来自同一池的连接吗?如果给MongoClient调用不同的参数会怎样?
greenlets ×13
python ×12
gevent ×9
python-3.x ×2
asynchronous ×1
concurrency ×1
django ×1
docker ×1
fork ×1
gil ×1
javascript ×1
logging ×1
mongodb ×1
node.js ×1
nonblocking ×1
python-2.7 ×1
webserver ×1
wsgi ×1
zeromq ×1