我有一个非常简单的Python 3脚本:
f1 = open('a.txt', 'r')
print(f1.readlines())
f2 = open('b.txt', 'r')
print(f2.readlines())
f3 = open('c.txt', 'r')
print(f3.readlines())
f4 = open('d.txt', 'r')
print(f4.readlines())
f1.close()
f2.close()
f3.close()
f4.close()
Run Code Online (Sandbox Code Playgroud)
但它总是说:
IOError: [Errno 32] Broken pipe
Run Code Online (Sandbox Code Playgroud)
我在互联网上看到了解决这个问题的所有复杂方法,但是我直接复制了这个代码,所以我认为代码有问题而不是Python的SIGPIPE.
我正在重定向输出,所以如果上面的脚本命名为"open.py",那么我的运行命令是:
open.py | othercommand
Run Code Online (Sandbox Code Playgroud) 我在python中编写了一个简单的多线程游戏服务器,为每个客户端连接创建一个新线程.我发现时不时,服务器会因为管道损坏/ SIGPIPE错误而崩溃.当程序试图将响应发送回不再存在的客户端时,我非常确定它正在发生.
处理这个问题的好方法是什么?我的首选解决方案只是关闭与客户端的服务器端连接并继续,而不是退出整个程序.
PS:这个问题/答案以一般方式处理问题; 具体应该如何解决?
我写了一个基于posix套接字的客户端程序.该程序创建多个线程,并将锁定服务器.但是在gdb时间调试期间,程序会给出一个信息(错误)
Run Code Online (Sandbox Code Playgroud)(gdb) n Program received signal SIGPIPE, Broken pipe. [Switching to Thread 0xb74c0b40 (LWP 4864)] 0xb7fdd424 in __kernel_vsyscall () (gdb)
这是代码:
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int get_hostname_by_ip(char* h , char* ip)
{
struct hostent *he;
struct in_addr **addr_list;
int i;
if ((he = gethostbyname(h)) == NULL)
{
perror("gethostbyname");
return 1;
}
addr_list = (struct in_addr **) he->h_addr_list;
for(i = 0; addr_list[i] != NULL; i++) …Run Code Online (Sandbox Code Playgroud) 如何运行带有管道的命令|?
子进程模块看起来很复杂......
有没有类似的东西
output,error = `ps cax | grep something`
Run Code Online (Sandbox Code Playgroud)
在shell脚本中?
问题:有没有办法使用flush=True该print()功能而无法获得BrokenPipeError?
我有一个脚本pipe.py:
for i in range(4000):
print(i)
Run Code Online (Sandbox Code Playgroud)
我从Unix命令行这样称呼它:
python3 pipe.py | head -n3000
Run Code Online (Sandbox Code Playgroud)
它返回:
0
1
2
Run Code Online (Sandbox Code Playgroud)
这个脚本也是如此:
import sys
for i in range(4000):
print(i)
sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)
但是,当我运行此脚本并将其传递给head -n3000:
for i in range(4000):
print(i, flush=True)
Run Code Online (Sandbox Code Playgroud)
然后我收到这个错误:
print(i, flush=True)
BrokenPipeError: [Errno 32] Broken pipe
Exception BrokenPipeError: BrokenPipeError(32, 'Broken pipe') in <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> ignored
Run Code Online (Sandbox Code Playgroud)
我也试过下面的解决方案,但我仍然得到BrokenPipeError:
import sys
for i in range(4000):
try:
print(i, flush=True)
except BrokenPipeError:
sys.exit()
Run Code Online (Sandbox Code Playgroud) 一个非常标准的C++ TCP服务器程序,使用pthreads,bind,listen和accept.我有一个场景,当我杀死一个连接的客户端时服务器结束(读取:崩溃).
崩溃的原因是write()对文件的调用失败,因此程序收到一个SIGPIPE.我想,这会让服务器退出.
我想,"当然,未处理的信号意味着退出",所以让我们使用signal():
signal(SIGPIPE, SIG_IGN);
Run Code Online (Sandbox Code Playgroud)
因为,取自man 2 write:
EPIPE fd 连接到读取端关闭的管道或插座.当发生这种情况时,写入过程也将收到SIGPIPE信号.(因此,仅当程序捕获,阻止或忽略此信号时才会看到写入返回值.)
唉,没有.无论是在服务器线程还是客户端线程中,这似乎都没有帮助.
那么,如何阻止write()呼叫发出该信号,或者(务实)如何阻止服务器退出.
我的诊断是:
pkill telnet崩溃客户端不需要的行为:服务器退出,在gdb中
... in write () at ../sysdeps/unix/syscall-template.S:82
82 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
Run Code Online (Sandbox Code Playgroud)
和回溯:
#0 ... in write () at ../sysdeps/unix/syscall-template.S:82
#1 ... in ClientHandler::mesg(std::string) ()
#2 ... in ClientHandler::handle() ()
#3 ... in …Run Code Online (Sandbox Code Playgroud) 所以我试图在Linux环境下学习C语言的套接字编程中SO_KEEPALIVE选项的用法.
我创建了一个服务器套接字并使用我的浏览器连接到它.它很成功,我能够阅读GET请求,但我仍然坚持使用SO_KEEPALIVE.
我查了这个链接keepalive_description@tldg.org但我找不到任何显示如何使用它的例子.
一旦我在accept()函数上检测到客户端的请求,我就在客户端套接字上设置SO_KEEPALIVE选项值1.现在我不知道如何检查客户端是否已关闭?,如何更改探测发送之间的时间间隔等.
我的意思是如何获得客户端关闭的信号(无需在客户端读取或写入...我认为当探测器未从客户端回复时我会得到一些信号),如何在设置选项后对其进行编程SO_KEEPALIVE上.
此外,如果假设探测器每隔3秒发送一次并且客户端介于两者之间,我将不会知道客户端已关闭,我可能会收到SIGPIPE.
无论如何,重要的是我想知道如何在代码中使用SO_KEEPALIVE.
在此先感谢一吨!
我正在研究在linux机器上使用epoll的网络程序,我收到了来自gdb的错误消息.
Program received signal SIGPIPE, Broken pipe.
[Switching to Thread 0x7ffff609a700 (LWP 19788)]
0x00007ffff7bcdb2d in write () from /lib/libpthread.so.0
(gdb)
(gdb) backtrace
#0 0x00007ffff7bcdb2d in write () from /lib/libpthread.so.0
#1 0x0000000000416bc8 in WorkHandler::workLoop() ()
#2 0x0000000000416920 in WorkHandler::runWorkThread(void*) ()
#3 0x00007ffff7bc6971 in start_thread () from /lib/libpthread.so.0
#4 0x00007ffff718392d in clone () from /lib/libc.so.6
#5 0x0000000000000000 in ?? ()
Run Code Online (Sandbox Code Playgroud)
我的服务器做了n ^ 2次计算,我试图用500个连接用户运行服务器.什么可能导致此错误?我该如何解决这个问题?
while(1){
if(remainLength >= MAX_LENGTH)
currentSentLength = write(client->getFd(), sBuffer, MAX_LENGTH);
else
currentSentLength = write(client->getFd(), sBuffer, remainLength);
if(currentSentLength == -1){
log("WorkHandler::workLoop, …Run Code Online (Sandbox Code Playgroud) 我想在tcp套接字中使用SO_NOSIGPIPE.
int set = 1;
setsockopt(sockDesc, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int);
Run Code Online (Sandbox Code Playgroud)
但是会出现错误:
error: SO_NOSIGPIPE was not declared in this scope
Run Code Online (Sandbox Code Playgroud)
是否需要任何头文件才能使用它.我通过互联网搜索但没有得到任何有用的解决方案.
我正在尝试测试一个被对等端优雅关闭的封闭套接字,而不会产生双重发送的延迟命中以引发SIGPIPE.
这里假设的一个假设是,在最后一次写入/发送之后,对等体在关闭后立即被对等体优雅地关闭.像过早关闭这样的实际错误将在代码中的其他地方处理.
如果套接字仍然打开,那么将有0个或更多字节数据,我实际上并不想从套接字缓冲区中取出.
我以为我可以打电话int ret = recv(sockfd, buf, 1, MSG_DONTWAIT | MSG_PEEK);来确定插座是否仍然连接.如果它的连接,但有一个在缓冲区中没有数据,我会得到的回报-1与errno == EAGAIN和返回的sockfd重用.如果它被对等方优雅地关闭,我将获得ret == 0并打开一个新连接.
我测试了这个,它似乎工作.但是,我怀疑在我收集数据的最后一位和同伴FIN到达时之间有一个小窗口,我可以EAGAIN从测试中得到假阳性recv.
这会咬我,还是有更好的方法呢?
c ×6
python ×4
sockets ×4
broken-pipe ×2
c++ ×2
linux ×2
python-3.x ×2
sigpipe ×2
tcp ×2
command ×1
flush ×1
gdb ×1
keep-alive ×1
networking ×1
pipe ×1
pthreads ×1
signals ×1
unix ×1