C 库从 BG 线程调用 kdb 函数
C-library invoking a kdb function from a BG-thread
我有一个外部 C 库,用于通过后台线程上的回调函数异步使用数据;我想接收数据并在 q 进程中处理它。根据 code.kx.com 的 Interfacing with C 文档,我制作了一个小的 C 库胶水代码,将入站源数据转换为 k 结构并将其分派到我的 q 进程 vi sd1/sd0 调用,以便q 函数在 q 的线程上下文中被调用。程序成功调用初始回调然后挂起。
我已将程序精简到我认为的最低限度,以简单地演示将 C BG 线程回调转换为 q 函数,但我不确定我是否精简了太多。例如,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]
感谢任何提示或意见。
你确定对方提供了足够的数据吗?正如我从您引用的文档中看到的那样,通信是通过使用 blocking 管道完成的。这意味着如果没有足够的数据,或者缓冲区没有被生产者刷新,你的应用程序应该阻塞,这是它的预期行为。
您可以尝试使用 sd0()/sd1()
跳过 d
参数来验证观察到的行为是由阻塞管道而不是其他原因引起的。
对于那些感兴趣的人,sd1 似乎安排了一个函数,每当文件描述符上有数据可供读取时调用,而 sd0 从调用中删除了计划的函数。
所以我的想法是编写一个尝试从 FD 读取的函数;如果成功,通过 k() 和 return 结果调用你的 q 函数,如果 0 只是 return 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;
}
我有一个外部 C 库,用于通过后台线程上的回调函数异步使用数据;我想接收数据并在 q 进程中处理它。根据 code.kx.com 的 Interfacing with C 文档,我制作了一个小的 C 库胶水代码,将入站源数据转换为 k 结构并将其分派到我的 q 进程 vi sd1/sd0 调用,以便q 函数在 q 的线程上下文中被调用。程序成功调用初始回调然后挂起。
我已将程序精简到我认为的最低限度,以简单地演示将 C BG 线程回调转换为 q 函数,但我不确定我是否精简了太多。例如,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]
感谢任何提示或意见。
你确定对方提供了足够的数据吗?正如我从您引用的文档中看到的那样,通信是通过使用 blocking 管道完成的。这意味着如果没有足够的数据,或者缓冲区没有被生产者刷新,你的应用程序应该阻塞,这是它的预期行为。
您可以尝试使用 sd0()/sd1()
跳过 d
参数来验证观察到的行为是由阻塞管道而不是其他原因引起的。
对于那些感兴趣的人,sd1 似乎安排了一个函数,每当文件描述符上有数据可供读取时调用,而 sd0 从调用中删除了计划的函数。
所以我的想法是编写一个尝试从 FD 读取的函数;如果成功,通过 k() 和 return 结果调用你的 q 函数,如果 0 只是 return 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;
}