总是使用neg [.zw]来确保所有消息都是异步的?

an *_*use 1 kdb

在服务器上考虑以下定义:

f:{show "Received ",string x; neg[.z.w] (`mycallback; x+1)}
Run Code Online (Sandbox Code Playgroud)

在客户端:

q)mycallback:{show "Returned ",string x;}
q)neg[h] (`f; 42)
q)"Returned 43"
Run Code Online (Sandbox Code Playgroud)

q for motrtals,提示说:

执行异步消息传递时,请始终使用neg [.zw]来确保所有消息都是异步的.否则,当每个进程等待另一个进程时,您将遇到死锁.

因此我将服务器上的定义更改为:

f:{show "Received ",string x; .z.w (`mycallback; x+1)}
Run Code Online (Sandbox Code Playgroud)

一切顺利,我没有看到任何僵局.

任何人都可以给我一个例子来说明为什么我应该总是使用neg[.z.w]

Joe*_*ths 7

如果我理解你的问题是正确的,我想你会问同步和异步消息是如何工作的.您提供的示例的问题是x + 1是一个非常简单的查询,几乎可以立即进行评估.对于更具说明性的示例,考虑将其更改为睡眠(或更艰苦的计算,例如,大型数据库查询).

在您的服务器端定义:

f:{show "Received ",string x;system "sleep 10"; neg[.z.w] (`mycallback; x+1)}
Run Code Online (Sandbox Code Playgroud)

然后在您的客户端,您可以发送同步查询:

h(`f; 42)
Run Code Online (Sandbox Code Playgroud)

多次.执行此操作,您将看到客户端不再有aq提示,因为它必须等待响应.这些请求可以排队,从而在很长一段时间内阻止客户端和服务器.

或者,如果你打电话:

(neg h)(`f; 42)
Run Code Online (Sandbox Code Playgroud)

在客户端.您将看到q提示仍然存在,因为客户端没有等待响应.这是一个异步调用.

现在,在您的服务器端函数中,您正在使用.zw或neg .zw这从服务器的角度来看,它遵循完全相同的主体.如果对查询的响应足够大,则消息传递可能会花费大量时间.因此,通过使用neg,可以异步发送此响应,因此在此过程中不会阻止服务器.

注意:如果您正在使用Windows机器,则需要更换睡眠以进行超时,或者如果您正在关注我的示例,则可能需要等待一段时间.

更新:我认为导致这种死锁的一种方法是拥有两个依赖进程,试图同步调用彼此.例如:

q)\p 10002
q)h:hopen 10003
q)g:{h (`f1;`)}
q)h (`f;`)' 
Run Code Online (Sandbox Code Playgroud)

在一边和

q)\p 10003
q)h:hopen 10002
q)f:{h (`g;`)}
q)f1:{show "test"}
Run Code Online (Sandbox Code Playgroud)

在另一.这将导致两个进程都被卡住,从而测试从未显示出来.