我有一个外部C库,用于通过后台线程上的回调函数异步使用数据;我想接收数据并在q过程中处理它。在code.kx.com的Interfacing with C文档之后,我创建了一个小型的胶水代码库,将入站源数据转换为k结构,并将其发送到我的q进程vi sd1 / sd0调用,以便q函数在q&#39的线程上下文中被调用。程序成功调用初始回调然后挂起。
我已经将程序剥离到了我认为只是简单地演示C-B线程回调到aq函数的最低限度,但是我不确定我是否也被剥离了许多。例如,sd1接受FD和C回调。我的最小FD是通过eventfd()创建的,该函数用于后续的sd1 / sd0调用。我尝试在FD上调用读取和写入,而不是通过FD执行任何IO,无论程序挂起。
这是我的骨架C库:
/* testlib.c */
#define KXVER 3
#include "k.h"
#include <pthread.h>
#include <sys/eventfd.h>
I d;
pthread_t tid;
K qdisp(I d)
{
K ignored = k(0, (S)"onCB", kj(54321), (K)0);
sd0(d);
return (K)0;
}
void* loop(void* vargs)
{
while(1) {
sleep(1);
sd1(d, qdisp);
}
return NULL;
}
K init(K ignore)
{
d = eventfd(1, 0);
int err = pthread_create(&tid, NULL, &loop, NULL);
return (K)0;
}
这是调用它的q脚本:
/ testlib.q
init:`testlib 2:(`init;1)
onCB:{ 0N!x }
init[`blah]
任何提示或评论都表示赞赏。
答案 0 :(得分:0)
您确定对方提供了足够的数据吗?正如我从您引用的文档中看到的那样,通过使用阻止管道进行通信。这意味着如果没有足够的数据,或生产者没有刷新缓冲区,则应用程序应阻止,这是其预期的行为。
您可以尝试使用sd0()/sd1()
跳过d
参数来验证观察到的行为是由阻塞管道引起的,而不是由其他内容引起的。
答案 1 :(得分:0)
对于那些感兴趣的人,看起来sd1会在每次有可用于在文件描述符上读取的数据时调度要调用的函数,并且sd0会从调用中删除调度的函数。
所以我的想法是编写一个试图从FD读取的函数;如果成功,则通过k()调用q函数并返回结果,如果0只返回0,如果错误调用sd0。
#define KXVER 3
#include "k.h"
#include <pthread.h>
#include <sys/eventfd.h>
#include <stdio.h>
I d;
pthread_t tid;
K qdisp(I d)
{
J v;
if (-1 != read(d, &v, sizeof(J)) ) {
return k(0, "onCB", ki(v), (K)0);
}
sd0(d);
return (K)0;
}
void* loop(void* vargs)
{
J j = 0;
sd1(d, qdisp);
while(j++) {
sleep(1);
write(d, &j, sizeof(J));
}
return NULL;
}
K init(K cb)
{
d = eventfd(1, 0);
int err = pthread_create(&tid, NULL, &loop, NULL);
return (K)0;
}