Linux Python、多线程、套接字有时无法创建
最近观察到一种相当奇怪的行为,这种行为只发生在Linux中,而不发生在freeBSD中。我想知道是否有人对此有解释,或者至少有人猜测到底发生了什么 问题: 套接字创建方法,Linux Python、多线程、套接字有时无法创建,linux,python-2.7,sockets,python-multithreading,low-level,Linux,Python 2.7,Sockets,Python Multithreading,Low Level,最近观察到一种相当奇怪的行为,这种行为只发生在Linux中,而不发生在freeBSD中。我想知道是否有人对此有解释,或者至少有人猜测到底发生了什么 问题: 套接字创建方法,socket.socket(),有时会失败。只有当多个线程创建套接字时才会发生这种情况,单线程工作正常 要扩展socket.socket()失败,大多数时候我会看到“错误13:权限被拒绝”,但我也看到了“错误93:协议不受支持” 注: 我在Ubuntu18.04(有bug)和FreeBSD12.0(没有bug)上试过这个 仅当
socket.socket()
,有时会失败。只有当多个线程创建套接字时才会发生这种情况,单线程工作正常
要扩展socket.socket()
失败,大多数时候我会看到“错误13:权限被拒绝”,但我也看到了“错误93:协议不受支持”
注:
从线程导入线程
导入套接字
def foo():
udp=socket.getprotobyname('udp')
尝试:
send_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM,udp)
例外情况除外,如e:
打印类型(e)
打印报告(e)
def main():
对于范围内的(6000):
t=线程(目标=foo)
t、 开始()
main()
注:
从技术上讲,我知道我可以通过让一个线程创建我需要的尽可能多的套接字并将它们作为参数传递给我的其他线程来解决我的问题,但这并不是真正的重点。我更感兴趣的是为什么会发生这种情况以及如何解决它,而不是可能有什么变通办法,尽管这些办法也很受欢迎。:) 我设法解决了它。问题来自
getprotobyname()
不是线程安全的
见:
另一方面,看看这些提示,这可能会导致并发问题,但是我的实验证明它不会,也许有人可以跟进
无论如何,对于任何感兴趣的人来说,固定版本的代码都是在主线程中获取协议号(似乎是明智的,并且应该首先这样做),然后将其作为参数传递。它既可以减少您执行的系统调用,又可以修复程序中与并发相关的任何问题。代码如下所示:
从线程导入线程
导入套接字
def foo(proto_num):
尝试:
send_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM,proto_num)
例外情况除外,如e:
打印类型(e)
打印报告(e)
def main():
proto_num=socket.getprotobyname('udp')
对于范围内的(6000):
t=Thread(target=foo,args=(proto_num,)
t、 开始()
main()
以“权限被拒绝”或“协议不受支持”形式创建套接字的异常不会以这种方式报告。另外,请注意,如果使用SOCK_DGRAM,则proto_编号是多余的,可能会被完全跳过,但是,如果有人想要创建SOCK_原始套接字,则解决方案将更为相关