python sokect默认多久断开
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python sokect默认多久断开相关的知识,希望对你有一定的参考价值。
参考技术A 在 Python 里面使用 socket 是相对简单的,连接成功以后可以 makefile(), 然后就跟读普通文件一样使用socket. 我们使用 beanstalkd 的客户度 beanstalkc 也是这样的,实现得很简洁。某一天 beanstalkd 所在的服务器不堪重负失去响应,导致整个应用被阻塞,不可用。罪魁祸首是beanstalkc,它用的是阻塞式的 socket, 不行,于是给它加了个 timeout, 就用 socket.settimeout().
自从设置了timeout, 就不断地冒出timeout异常,而 beanstalkd 看起来却是正常的。在给 beanstalkc 添加了多个后端支持后,居然经常出现N个后端以此超时的奇怪现象。经过调试发现,是某些比较大的对象会导致超时,不管超时时间设置多大。
原来,socket 一旦设置了timeout, 就进入了 non-blocking 工作模式,原来的 send() 和 recv() 等的用法就完全不同了,可能会只发送或者接收了部分数据,需要检查返回值并多次重试。甚至,makefile() 是完全不允许使用的,它已经在 socket 模块的文档中明确声明,不过如果不是在这里栽过跟头很少会注意到这点。
明确了这一点,就可以写出在 non-blocking 模式工作的正确代码,会复杂不少,尤其处理一开始不能确定数据长度的文本协议。
阻塞和非阻塞是完全两种不同的使用方法,并不是添加一个socket.settimeout() 那么简单。本回答被提问者采纳
python多久刷新一次文件?
【中文标题】python多久刷新一次文件?【英文标题】:How often does python flush to a file? 【发布时间】:2011-03-11 04:43:47 【问题描述】:-
Python 多久刷新一次文件?
Python 多久刷新一次到标准输出?
我不确定 (1)。
至于 (2),我相信 Python 在每个新行之后都会刷新到标准输出。但是,如果您将 stdout 重载到文件中,它是否会经常刷新?
【问题讨论】:
【参考方案1】:对于文件操作,Python 使用操作系统的默认缓冲,除非您另外配置。您可以指定缓冲区大小、无缓冲或行缓冲。
例如,open 函数采用缓冲区大小参数。
http://docs.python.org/library/functions.html#open
"可选的缓冲参数指定文件所需的缓冲区大小:"
0 表示无缓冲, 1 表示行缓冲, 任何其他正值表示使用(大约)该大小的缓冲区。 负缓冲意味着使用系统默认值,通常对 tty 设备进行行缓冲,对其他文件进行完全缓冲。 如果省略,则使用系统默认值。代码:
bufsize = 0
f = open('file.txt', 'w', buffering=bufsize)
【讨论】:
+1 表示“行缓冲”部分。这正是我一直在寻找的东西,它就像一个魅力。 当我使用 Python 3.4.3open('file.txt', 'w', 1)
我得到了正确的行缓冲。但如果我做更大的事情(我想要open('file.txt', 'w', 512)
),它会缓冲 8192 的完整io.DEFAULT_BUFFER_SIZE
。这是 Python 错误、Linux 错误还是 ID10t 错误?
是否可以更改已打开流的缓冲?比如说,我希望 stdout
被行缓冲,无论它是控制台还是重定向到文件?
@CharlieParker 当您在文件句柄上调用write()
时,输出会缓冲在内存中并累积直到缓冲区已满......此时缓冲区被“刷新”(内容被写入从缓冲区到文件)。您可以通过在文件句柄上调用flush()
方法来显式刷新缓冲区。
请注意,无缓冲 (0) 仅在二进制模式下可用,而行缓冲 (1) 仅在文本模式下可用。【参考方案2】:
您还可以使用flush()
方法以编程方式将缓冲区强制刷新到文件中。
with open('out.log', 'w+') as f:
f.write('output is ')
# some work
s = 'OK.'
f.write(s)
f.write('\n')
f.flush()
# some other work
f.write('done\n')
f.flush()
我发现这在使用 tail -f
跟踪输出文件时很有用。
【讨论】:
来自文档:Note: flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.
@bobismijnnaam 下次链接到上述文档。我能找到的唯一参考来自github.com/jprzywoski/python-reference/blob/master/source/docs/…,我不知道那是谁。
@Bruno Bronosky 好点。 Docs:Note: flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.
我很困惑的是flushing
这个词的含义。为什么我们需要它?它是干什么用的?我为什么要关心它?
@CharlieParker 写入时,会写入 RAM 中文件的(部分)副本,该文件可能暂时不会保存到磁盘。它提高了性能,但如果该副本从未被写入(磁盘移除、操作系统崩溃等),则可能意味着数据丢失。 flush() 告诉 Python 立即将该缓冲区写回磁盘。 (然后,os.fsync() 告诉操作系统也这样做。缓冲区有很多层......)【参考方案3】:
我不知道这是否也适用于 python,但我认为这取决于您运行的操作系统。
例如,在 Linux 上,到终端的输出在换行符上刷新缓冲区,而对于文件的输出,它仅在缓冲区已满时才刷新(默认情况下)。这是因为刷新缓冲区的次数更少,效率更高,并且用户不太可能注意到输出是否没有在文件中的换行符上刷新。
如果你需要的话,你也许可以自动刷新输出。
编辑:我认为你会以这种方式在 python 中自动刷新(基于 来自here)
#0 means there is no buffer, so all output
#will be auto-flushed
fsock = open('out.log', 'w', 0)
sys.stdout = fsock
#do whatever
fsock.close()
【讨论】:
【参考方案4】:您还可以通过调用 io 模块中的只读 DEFAULT_BUFFER_SIZE 属性来检查默认缓冲区大小。
import io
print (io.DEFAULT_BUFFER_SIZE)
【讨论】:
谢谢!很高兴知道 python 将其设置为操作系统定义...但这有助于找出操作系统预定义的什么。【参考方案5】:这是另一种方法,由 OP 选择他喜欢的方法。
当在任何其他代码之前在__init__
.py 文件中包含以下代码时,使用print
打印的消息和任何错误将不再记录到 Ableton 的 Log.txt,而是记录到磁盘上的单独文件中:
import sys
path = "/Users/#username#"
errorLog = open(path + "/stderr.txt", "w", 1)
errorLog.write("---Starting Error Log---\n")
sys.stderr = errorLog
stdoutLog = open(path + "/stdout.txt", "w", 1)
stdoutLog.write("---Starting Standard Out Log---\n")
sys.stdout = stdoutLog
(对于 Mac,将 #username#
更改为您的用户文件夹的名称。在 Windows 上,您的用户文件夹的路径将具有不同的格式)
当您在文本编辑器中打开文件时,当磁盘上的文件发生更改时会刷新其内容(Mac 的示例:TextEdit 不会,但 TextWrangler 会),您将看到实时更新的日志。
致谢:这段代码大部分是从 Nathan Ramella 的 liveAPI 控制界面脚本中复制而来的
【讨论】:
以上是关于python sokect默认多久断开的主要内容,如果未能解决你的问题,请参考以下文章
微信硬件平台 设备控制控制面板-网页sokect-mqtt长连接