PHP socket_read/recv 阻塞 python 的 socket.send
PHP socket_read/recv blocking python's socket.send
我正在 Python 在 Linux 上使用 JS+PHP 客户端构建一个 Firebird DB 事务管理器。 Javascript 将所有必要的信息发送到 PHP; PHP 对此进行编码并通过套接字将其发送到 Python,它有一个绑定到端口的套接字不断监听并使用线程创建一个新线程来异步处理该请求。
python中的接受循环:
while 1:
conn, addr = s.accept()
req = conn.recv(1024)
ret = read_headers(req)
threading.Thread(target=client_thread, args=(conn, addr, ret, smphr,)).start()
s.close()
php中的send/read块:
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$sockconnect = socket_connect($sock, $host, $port);
$msg = urldecode(http_build_query($params));
socket_write($sock, $msg, strlen($msg));
$received;
while(socket_recv($sock, $buf, 1024, 0) >= 1){
$received .= $buf;
}
echo $received;
socket_close($sock);
在我们开始使用更大数量的连接进行测试之前,一切似乎都运行正常。我在 JS 客户端中有一个循环,它发送几个(25-100 是我到目前为止使用的数字)查询请求,其中 select 第一个随机行数来自一个大 table .
服务器收到的前几个请求是同时处理的,但后来似乎变成了同步。
经过多次记录,发现在任何给定时间只有 7/8 个线程处于活动状态。只有在 7 个当前请求之一完成后,新请求才会被接受和处理。
如果我在 php 中评论 socket_recv while 循环,python 将同时 运行 所有内容,并且 return 一旦可用,正是我想要的,但由于我已经评论了实际获得结果的块,所以没有显示任何内容(显然)。
每个 request/queries 都被记录为不同的脚本调用(根据 chrome 的网络开发工具)所以我不知道为什么它们会互相阻塞。
我在 php/python 还很陌生,我这辈子都搞不清楚到底发生了什么。
有什么建议吗?
编辑:
我还尝试了不同的代码位来读取 php 中的响应(none 按预期工作):
$buf = 'buffer';
socket_recv($sock, $buf, 1024, MSG_WAITALL);
echo $buf;
与之前的实现相同,7/8 线程 'limit'
$buf = 'buffer';
socket_recv($sock, $buf, 1024, MSG_DONTWAIT);
echo $buf;
正如标志所暗示的,不等待响应,因此没有响应
while ($out = socket_read($sock, 1024, PHP_NORMAL_READ)) {
echo $out;
}
同一线程 7/8 线程限制。
第二次编辑:
添加了 Python 打印,以防有帮助。
随读入php:
starting select first 3000 * from receb_quotas on tr1
starting select first 1 * from receb_quotas on tr0
starting select first 1 * from receb_quotas on tr2
starting select first 1 * from receb_quotas on tr4
starting select first 3000 * from receb_quotas on tr3
starting select first 3000 * from receb_quotas on tr5
finishing tr4 (count: 1) | remaining threads: 7
finishing tr0 (count: 1) | remaining threads: 7
starting select first 150 * from receb_quotas on tr8
starting select first 3000 * from receb_quotas on tr6
finishing tr2 (count: 1) | remaining threads: 7
starting select first 1 * from receb_quotas on tr7
finishing tr7 (count: 1) | remaining threads: 7
starting select first 3000 * from receb_quotas on tr9
finishing tr8 (count: 150) | remaining threads: 7
finishing tr1 (count: 3000) | remaining threads: 6
finishing tr3 (count: 3000) | remaining threads: 5
finishing tr6 (count: 3000) | remaining threads: 4
finishing tr5 (count: 3000) | remaining threads: 3
finishing tr9 (count: 3000) | remaining threads: 2
没有php读:
starting select first 3000 * from receb_quotas on tr1
starting select first 15 * from receb_quotas on tr0
starting select first 15 * from receb_quotas on tr3
starting select first 3000 * from receb_quotas on tr4
starting select first 1500 * from receb_quotas on tr2
starting select first 150 * from receb_quotas on tr5
starting select first 1 * from receb_quotas on tr6
starting select first 1500 * from receb_quotas on tr7
starting select first 150 * from receb_quotas on tr8
starting select first 15 * from receb_quotas on tr9
finishing tr0 (count: 15) | remaining threads: 11
finishing tr3 (count: 15) | remaining threads: 10
finishing tr6 (count: 1) | remaining threads: 9
finishing tr9 (count: 15) | remaining threads: 8
finishing tr8 (count: 150) | remaining threads: 7
finishing tr5 (count: 150) | remaining threads: 6
finishing tr7 (count: 1500) | remaining threads: 5
finishing tr2 (count: 1500) | remaining threads: 4
finishing tr1 (count: 3000) | remaining threads: 3
finishing tr4 (count: 3000) | remaining threads: 2
似乎确实没有在 php 中读取,所有查询都是同时启动的,并且 return 准备就绪后立即编辑。
原来是浏览器问题。 Chrome(也许其他现代浏览器)最多只支持同时调用 6 个 ajax。
因为我有 7 个线程 'cap',其中一个是主线程。这完全符合。
我正在 Python 在 Linux 上使用 JS+PHP 客户端构建一个 Firebird DB 事务管理器。 Javascript 将所有必要的信息发送到 PHP; PHP 对此进行编码并通过套接字将其发送到 Python,它有一个绑定到端口的套接字不断监听并使用线程创建一个新线程来异步处理该请求。
python中的接受循环:
while 1:
conn, addr = s.accept()
req = conn.recv(1024)
ret = read_headers(req)
threading.Thread(target=client_thread, args=(conn, addr, ret, smphr,)).start()
s.close()
php中的send/read块:
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$sockconnect = socket_connect($sock, $host, $port);
$msg = urldecode(http_build_query($params));
socket_write($sock, $msg, strlen($msg));
$received;
while(socket_recv($sock, $buf, 1024, 0) >= 1){
$received .= $buf;
}
echo $received;
socket_close($sock);
在我们开始使用更大数量的连接进行测试之前,一切似乎都运行正常。我在 JS 客户端中有一个循环,它发送几个(25-100 是我到目前为止使用的数字)查询请求,其中 select 第一个随机行数来自一个大 table .
服务器收到的前几个请求是同时处理的,但后来似乎变成了同步。
经过多次记录,发现在任何给定时间只有 7/8 个线程处于活动状态。只有在 7 个当前请求之一完成后,新请求才会被接受和处理。
如果我在 php 中评论 socket_recv while 循环,python 将同时 运行 所有内容,并且 return 一旦可用,正是我想要的,但由于我已经评论了实际获得结果的块,所以没有显示任何内容(显然)。
每个 request/queries 都被记录为不同的脚本调用(根据 chrome 的网络开发工具)所以我不知道为什么它们会互相阻塞。
我在 php/python 还很陌生,我这辈子都搞不清楚到底发生了什么。
有什么建议吗?
编辑: 我还尝试了不同的代码位来读取 php 中的响应(none 按预期工作):
$buf = 'buffer';
socket_recv($sock, $buf, 1024, MSG_WAITALL);
echo $buf;
与之前的实现相同,7/8 线程 'limit'
$buf = 'buffer';
socket_recv($sock, $buf, 1024, MSG_DONTWAIT);
echo $buf;
正如标志所暗示的,不等待响应,因此没有响应
while ($out = socket_read($sock, 1024, PHP_NORMAL_READ)) {
echo $out;
}
同一线程 7/8 线程限制。
第二次编辑:
添加了 Python 打印,以防有帮助。
随读入php:
starting select first 3000 * from receb_quotas on tr1
starting select first 1 * from receb_quotas on tr0
starting select first 1 * from receb_quotas on tr2
starting select first 1 * from receb_quotas on tr4
starting select first 3000 * from receb_quotas on tr3
starting select first 3000 * from receb_quotas on tr5
finishing tr4 (count: 1) | remaining threads: 7
finishing tr0 (count: 1) | remaining threads: 7
starting select first 150 * from receb_quotas on tr8
starting select first 3000 * from receb_quotas on tr6
finishing tr2 (count: 1) | remaining threads: 7
starting select first 1 * from receb_quotas on tr7
finishing tr7 (count: 1) | remaining threads: 7
starting select first 3000 * from receb_quotas on tr9
finishing tr8 (count: 150) | remaining threads: 7
finishing tr1 (count: 3000) | remaining threads: 6
finishing tr3 (count: 3000) | remaining threads: 5
finishing tr6 (count: 3000) | remaining threads: 4
finishing tr5 (count: 3000) | remaining threads: 3
finishing tr9 (count: 3000) | remaining threads: 2
没有php读:
starting select first 3000 * from receb_quotas on tr1
starting select first 15 * from receb_quotas on tr0
starting select first 15 * from receb_quotas on tr3
starting select first 3000 * from receb_quotas on tr4
starting select first 1500 * from receb_quotas on tr2
starting select first 150 * from receb_quotas on tr5
starting select first 1 * from receb_quotas on tr6
starting select first 1500 * from receb_quotas on tr7
starting select first 150 * from receb_quotas on tr8
starting select first 15 * from receb_quotas on tr9
finishing tr0 (count: 15) | remaining threads: 11
finishing tr3 (count: 15) | remaining threads: 10
finishing tr6 (count: 1) | remaining threads: 9
finishing tr9 (count: 15) | remaining threads: 8
finishing tr8 (count: 150) | remaining threads: 7
finishing tr5 (count: 150) | remaining threads: 6
finishing tr7 (count: 1500) | remaining threads: 5
finishing tr2 (count: 1500) | remaining threads: 4
finishing tr1 (count: 3000) | remaining threads: 3
finishing tr4 (count: 3000) | remaining threads: 2
似乎确实没有在 php 中读取,所有查询都是同时启动的,并且 return 准备就绪后立即编辑。
原来是浏览器问题。 Chrome(也许其他现代浏览器)最多只支持同时调用 6 个 ajax。
因为我有 7 个线程 'cap',其中一个是主线程。这完全符合。