我有一项任务是使用freebsd中的raymond算法构建对分布式互斥的支持。
这要求内核线程始终在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);
答案 0 :(得分:1)
考虑使用netgraph,它已准备好使用ng_ksocket模块。
答案 1 :(得分:1)
对socreate
的调用恐慌,因为mainproc->p_singlethread
是NULL
。此变量不是与流程关联的线程,而是用于在流程中强制执行“单线程”(有关详细信息,请参阅thread_single()
中的函数sys/kern/kern_thread.c
)。
您可能想要做的是使用curthread
res = socreate(AF_INET, &listenso, SOCK_DGRAM, IPPROTO_UDP,
curthread->td_ucred, curthread);
...
res = sobind(listenso, (struct sockaddr*)&listenadr, curthread);