C库从BG线程

时间:2016-05-26 20:01:43

标签: c multithreading kdb

我有一个外部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]

任何提示或评论都表示赞赏。

2 个答案:

答案 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;
}