在 freebsd 中使用内核线程的正确方法(+ 网络)

发布于 2024-11-18 03:42:37 字数 1993 浏览 2 评论 0原文

我有一项任务是在 freebsd 中使用雷蒙德算法构建对分布式互斥的支持。

这需要内核线程始终在 udp 端口​​上侦听来自其他系统的消息并采取相应的操作。

我正在使用 thread_create 创建一个线程,但在每次调用 socreate 时都会产生内核恐慌。 做我正在做的事情的最佳方法是什么?我在 freebsd 中找不到任何关于内核网络的好的教程。

另一方面,也许 mainproc 变量设置不正确。如何找到当前的 struct proc*struct thread*

我当前的代码是这样的:

static struct proc *mainproc;
static int val;
static int main_thread_finish;

static struct socket *listenso;
static struct sockaddr_in listenadr;

static void main_thread(void* data)
{
    static int res;
    printf("In thread\n");
    res = socreate(AF_INET, &listenso, SOCK_DGRAM, IPPROTO_UDP, mainproc->p_ucred, mainproc->p_singlethread);
    printf("socreate res: %d\n", res);

    listenadr.sin_family = AF_INET;
    listenadr.sin_port = htons(1234);
    listenadr.sin_addr.s_addr = 0;
    res = sobind(listenso, (struct sockaddr*)&listenadr, mainproc->p_singlethread);
    printf("bind res: %d\n", res);

    while(!main_thread_finish)
    {
            pause("DUMMY", hz);
    }
    printf("kthread exiting...\n");
   kthread_exit();
}

static int
raymond_module_load(struct module *module, int cmd, void *arg)
{
    int error = 0;

    switch (cmd) {
    case MOD_LOAD :
            val = 12345;
            main_thread_finish = 0;
            kproc_create(main_thread, NULL, &mainproc, 0, 0, "raymond_main_thread");
            printf("Module loaded - kthread created\n");
            break;
    case MOD_UNLOAD :
            main_thread_finish = 1;
            printf("Waiting for thread to exit...\n");
            pause("TWAIT", 3*hz);
            printf("Module unload...\n");
            break;
    default :
            error = EOPNOTSUPP;
            break;
    }
    return (error);
}

static moduledata_t raymond_module_data = {
    .name = "raymond_module",
    .evhand = raymond_module_load,
    .priv = NULL };

DECLARE_MODULE(raymond_module, raymond_module_data, SI_SUB_KLD, SI_ORDER_ANY);

I have an assignment to build support for distributed mutual exclusion using raymond's algorithm in freebsd.

This requires a kernel thread to always listen on a udp port for messages from other systems and act accordingly.

I'm creating a thread using thread_create, but inside every call to socreate creates a kernel panic.
What's the best way to do what I'm doing? I couldn't find any good tutorials on kernel networking in freebsd.

On another note, maybe the mainproc variable is not set correctly. How can I find out current struct proc* or struct thread*?

My current code is like this:

static struct proc *mainproc;
static int val;
static int main_thread_finish;

static struct socket *listenso;
static struct sockaddr_in listenadr;

static void main_thread(void* data)
{
    static int res;
    printf("In thread\n");
    res = socreate(AF_INET, &listenso, SOCK_DGRAM, IPPROTO_UDP, mainproc->p_ucred, mainproc->p_singlethread);
    printf("socreate res: %d\n", res);

    listenadr.sin_family = AF_INET;
    listenadr.sin_port = htons(1234);
    listenadr.sin_addr.s_addr = 0;
    res = sobind(listenso, (struct sockaddr*)&listenadr, mainproc->p_singlethread);
    printf("bind res: %d\n", res);

    while(!main_thread_finish)
    {
            pause("DUMMY", hz);
    }
    printf("kthread exiting...\n");
   kthread_exit();
}

static int
raymond_module_load(struct module *module, int cmd, void *arg)
{
    int error = 0;

    switch (cmd) {
    case MOD_LOAD :
            val = 12345;
            main_thread_finish = 0;
            kproc_create(main_thread, NULL, &mainproc, 0, 0, "raymond_main_thread");
            printf("Module loaded - kthread created\n");
            break;
    case MOD_UNLOAD :
            main_thread_finish = 1;
            printf("Waiting for thread to exit...\n");
            pause("TWAIT", 3*hz);
            printf("Module unload...\n");
            break;
    default :
            error = EOPNOTSUPP;
            break;
    }
    return (error);
}

static moduledata_t raymond_module_data = {
    .name = "raymond_module",
    .evhand = raymond_module_load,
    .priv = NULL };

DECLARE_MODULE(raymond_module, raymond_module_data, SI_SUB_KLD, SI_ORDER_ANY);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青春如此纠结 2024-11-25 03:42:37

socreate 的调用会发生混乱,因为 mainproc->p_singlethreadNULL。该变量不是与进程关联的线程,而是用于在进程内强制执行“单线程”(请参阅​​ sys/kern/kern_thread.c 中的函数 thread_single()代码> 了解更多详细信息)。

可能您想要做的是使用 curthread

res = socreate(AF_INET, &listenso, SOCK_DGRAM, IPPROTO_UDP,
            curthread->td_ucred, curthread);
...
res = sobind(listenso, (struct sockaddr*)&listenadr, curthread);

The call to socreate panics because mainproc->p_singlethread is NULL. This variable is not the thread associated with the process but is used to enforce "single-threading" within a process (see the function thread_single() in sys/kern/kern_thread.c for more details).

Probably what you wanted to do was was to use curthread

res = socreate(AF_INET, &listenso, SOCK_DGRAM, IPPROTO_UDP,
            curthread->td_ucred, curthread);
...
res = sobind(listenso, (struct sockaddr*)&listenadr, curthread);
向地狱狂奔 2024-11-25 03:42:37

考虑使用netgraph,它已经准备好使用ng_ksocket模块。

Consider using netgraph, it has ready to use ng_ksocket module.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文