始终使用neg [.z.w]来确保所有消息都是异步的吗?

时间:2018-09-13 02:49:08

标签: kdb

请考虑服务器上的以下定义:

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

在客户端:

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

q for motrtals中,提示说:

  

执行异步消息传递时,请始终使用neg [.z.w]来确保   所有消息都是异步的。否则你会陷入僵局   因为每个进程都在等待对方。

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

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

一切都很好,而且我还没有看到任何僵局。

谁能给我一个例子来说明为什么我应该始终使用neg[.z.w]

2 个答案:

答案 0 :(得分:7)

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

在服务器端定义:

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

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

h(`f; 42)

多次。这样做,您将看到客户端不再有q提示,因为它必须等待响应。这些请求可以排队,从而在相当长的时间内阻塞了客户端和服务器。

或者,如果您要致电:

(neg h)(`f; 42)

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

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

注意:如果您在Windows计算机上工作,则需要按照睡眠方式换掉超时,或者如果遵循我的示例,则可能需要进行while循环。

更新:我想导致这种死锁的一种方法是拥有两个从属进程,试图彼此同步调用。例如:

q)\p 10002
q)h:hopen 10003
q)g:{h (`f1;`)}
q)h (`f;`)' 

一侧和

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

另一方面。这将导致两个进程都卡住,从而导致永远无法显示测试。

答案 1 :(得分:0)

Joe的答案涵盖了几乎所有内容,但是对于您的特定示例,如果客户致电

,则会发生死锁
h (`f; 42)

在处理下一个请求之前,客户端正在等待服务器的响应,但是在完成客户端的请求之前,服务器也在等待客户端的响应。