我想在不使用任何POSIX库的情况下在C中实现多线程。 任何帮助将不胜感激。
不:不要使用fork()或vfork()。
答案 0 :(得分:12)
Linux中的线程本质上是一个与其父级共享内存和资源的进程。 Linux内核不区分进程和线程,换句话说,Linux中没有轻量级进程的概念,就像在其他一些操作系统中一样。 Linux中的线程实现为标准进程,因此可以使用clone()
创建一个线程,通常由fork()
以下列方式调用:
clone(SIGCHLD, 0);
这只会克隆信号处理程序,但是,使用适当的标志可以创建一个线程:
clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0);
这与前一个调用相同,只是地址空间,文件系统资源,文件描述符和信号处理程序由两个进程共享。
另一种方法是使用user-level threads(也称为光纤),这些是在用户级实现的执行线程,这意味着操作系统不知道这些线程和调度或上下文切换< / em>必须在用户级别完成。大多数用户级调度程序都实现为协作调度程序,但也可以使用简单的round robin scheduling实现抢占式调度程序。
查看clone(2)手册页以获取详细信息,如果您想了解更多信息,我建议Linux Kernel Development第3版作者:Robert Love,(不以任何方式与作者有关),请查看内部链接你可以在线阅读其中一些内容。对于用户级线程,有一个由我编写的最小包,称为libutask,它实现了一个协作和一个抢占式调度程序,你可以根据需要检查源代码。
注1:据我所知,我没有提到UNIX,这是特定于Linux的实现。
注意2:使用clone创建自己的线程不是一个真实的解决方案,请阅读您可能需要处理的一些问题的注释,这只是一个问题的答案是可以创建线程而不使用pthreads,在这种情况下答案是肯定的。
答案 1 :(得分:3)
您还可以从C标准库中查看新的<threads.h>
标头。 (C11)
它有你需要的int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
以及互斥函数和条件变量。
答案 2 :(得分:3)
请参阅:
对于类似UNIX的系统,。
另见:
用于BSD和现代UNIX。
这个page给出了许多使用这些原语的准系统实现的例子。
您可以使用原子指令来实现锁定原语(互斥锁,信号量)。
我还建议查看用户态线程库的实际实现以获得一些提示。请参阅this page,其中列出了Linux的实现。
最后,您可能希望获得有关coroutines和trampolines的一些信息,但后者并不是那么密切相关。
答案 3 :(得分:2)
最重要的是,几乎任何操作系统都能在平均c上创建至少一个合作微内核。从根本上说,它只需要克隆堆栈帧(并相应地调整几个指针 - 尤其是从函数返回地址到其他线程的当前返回地址)。还有一些实用函数,比如“上下文切换”堆栈就可以堆积和返回。
如果允许带有回调的定时器中断,可以执行先发制人的微内核。
至少Dr Dobbs和IOCCC已经提出了这些方案的选择。