我想在不使用任何 POSIX 库的情况下在 C 中实现多线程。任何帮助,将不胜感激。
不:不要使用 fork() 或 vfork()。
我想在不使用任何 POSIX 库的情况下在 C 中实现多线程。任何帮助,将不胜感激。
不:不要使用 fork() 或 vfork()。
Linux 中的线程本质上是一个与其父进程共享内存和资源的进程。Linux内核不区分进程和线程,换句话说,Linux中没有像其他一些操作系统那样的轻量级进程的概念。Linux 中的线程是作为标准进程实现的,因此可以使用clone()
通常通过fork()
以下方式调用的线程来创建线程:
clone(SIGCHLD, 0);
这仅克隆信号处理程序,但是,您可以使用适当的标志创建线程:
clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0);
这与前面的调用相同,只是地址空间、文件系统资源、文件描述符和信号处理程序由两个进程共享。
另一种方法是使用用户级线程(也称为光纤),这些线程是在用户级实现的执行线程,这意味着操作系统不知道这些线程,并且必须在用户处完成调度或上下文切换。等级。大多数用户级调度器都是作为协作调度器实现的,但也可以通过简单的 循环调度来实现抢占式调度器。
查看clone(2)手册页以获取详细信息,如果您想了解更多信息,我推荐 Robert Love 的Linux Kernel Development 3rd edition,(与作者没有任何关联)有一个查看内部链接,您可以阅读其中的一些内容在线的。至于用户级线程,我写了一个最小的包,叫做libutask,它实现了协作调度器和抢占式调度器,如果你喜欢,你可以查看源代码。
注意1:我没有提到UNIX,据我所知,这是Linux特定的实现。
注意2:使用克隆创建自己的线程并不是一个现实世界的解决方案,请阅读评论以了解您可能必须处理的一些问题,这只是对是否可以在不使用 pthreads 的情况下创建线程的问题的回答,在这种情况下答案是肯定的。
看:
对于类 UNIX 系统。
另见:
适用于 BSD 和现代 UNIX。
此页面提供了许多使用这些原语等的准系统实现示例。
您可以使用原子指令来实现锁定原语(互斥体、信号量)。
我还建议查看用户态线程库的实际实现以获得一些提示。请参阅此页面,该页面提供了 Linux 的实现列表。
最后,您可能想了解一些关于coroutines和可能的trampolines的信息,尽管后者的相关性并不那么密切。
<threads.h>
您还可以从 C 标准库中查看新的头文件。(C11)
它有你需要的东西int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
以及互斥函数和条件变量。
One can most certainly make at least a co-operative microkernel with plain c on top of pretty much any operating system. Fundamentally it only requires cloning of the stack frame (and adjusting a few pointers accordingly -- especially the return address from a function to the other threads current return address). And a few utility functions, such as "context switch" the stack to heap and back.
If a timer interrupt with a callback is allowed, one can do a pre-emptive microkernel.
At least Dr Dobbs and IOCCC have presented options along these lines.