开发者

"thread fork" in C (ideally POSIX, but just Linux works)

Are there any libraries/pthread wrappers/clone arguments that would allow me to have a tfork--something that, just like fork(), allows you to continue code execution in context, as opposed to pointing to a new function to execute under a new thread.

If 开发者_如何学Gonot, is there any simple way to write this myself?


Usage would be ideally just like fork but the meaning would be threadlike, so as a contrived example:

int main() {
        int ival = 0;
        if(tfork() == 0) {
                sleep(10);
                ival = 5;
                _exit(); // or exit or return or whatever
        } else {
                while(1) {
                        printf("ival=%d\n", ival);
                        if(ival != 0) {
                                printf("ival changed. done.\n");
                                return 0;
                        }
                        sleep(1);
                }
        }
}

Should output:

ival=0
ival=0
ival=0
ival=0
ival=0
ival=0
ival=0
ival=0
ival=0
ival=0
ival=5
ival changed. done.


You can't do that, because threads share the same address-space. Continuing from the same execution context (like fork() does) would mean that their stacks were in the same memory.

Of course two threads needs to have their own stacks otherwise trouble would happen.

This is why you need to specify a function to start a new thread - because the new thread has a new stack.


You can kind of do stuff like this with openMP

It's not precisely like this, but it does do the thread creation automagically, and there are mechanisms for synchronization and communication.


Uh, this is almost what vfork() does on Linux, it shares the memory of the parent (but doesn't share the rest of the things that threads are supposed to share).

Since sharing the memory of the parent leads to the problems that have been talked about in the comments to your question (snd some other problems), a vfork() parent is actually suspended until the child drops all references to that memory, usually via execve() or _exit() (Note the underscore, exit() is not safe on a vfork() child).

The only things a vfork() child is guaranteed to be able to do safely are calling exec*() or _exit(). With a lot of knowledge and black voodoo magic, some people can do more things on a vfork() child on Linux, but this involves a lot of attention to detail.

So, as you can see, there are a lot of limitations to the things you can do when sharing memory and returning a la fork(): there is a very good reason why thread creation usually is done by calling a function.


In Linux, fork() and pthread_create() are just a wrapper over clone(). You call call clone() directly yourself to get the desired effect. For example (not actual code but very close):

pid = syscall(SYS_clone, (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM | CLONE_PARENT), NULL, NULL, NULL );

if(-1 == pid) { 
    return -1;
}

if(pid) {
          return pid;
    } else {

     // Your new thread code goes here
   }

More details here: http://linux.die.net/man/2/clone

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜