"Thread Fork" в C (в идеале POSIX, но только Linux работает) - PullRequest
3 голосов
/ 03 июня 2011

Существуют ли какие-либо библиотеки / pthread wrappers / clone аргументы, которые позволили бы мне иметь tfork - то, что, как и fork(), позволяет вам продолжать выполнение кода в контексте, а не указывать нановая функция для выполнения в новом потоке.

Если нет, есть ли простой способ написать это сам?


В идеальном случае использование было бы таким же, как fork, но значение было бы нитевидным, так что в качестве надуманного примера:

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);
                }
        }
}

Следует вывести:

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.

Ответы [ 4 ]

5 голосов
/ 04 июня 2011

Вы не можете этого сделать, потому что потоки используют одно и то же адресное пространство. Продолжение из того же контекста выполнения (как делает fork ()) будет означать, что их стеки находятся в одной и той же памяти.

Конечно, два потока должны иметь свои собственные стеки, иначе могут возникнуть проблемы.

Вот почему вам нужно указать функцию для запуска нового потока - потому что новый поток имеет новый стек.

1 голос
/ 04 июня 2011

В Linux fork () и pthread_create () являются просто оберткой над clone ().Вы сами вызываете clone (), чтобы получить желаемый эффект.Например (не фактический код, но очень близко):

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
   }

Подробнее здесь: http://linux.die.net/man/2/clone

1 голос
/ 04 июня 2011

Э-э, это почти то, что vfork() делает в Linux, он разделяет память родителя (но не разделяет остальное, что потоки должны совместно использовать).

Поскольку разделение памяти родителя приводит к проблемам, о которых говорилось в комментариях к вашему вопросу (и к некоторым другим проблемам), родительский vfork() фактически приостанавливается до тех пор, пока ребенок не отбросит все ссылки на эту память, обычно через execve() или _exit() (обратите внимание на подчеркивание, exit() небезопасно для vfork() ребенка).

Только вещи, которые ребенок vfork() может безопасно делать, вызывают exec*() или _exit(). Обладая большими знаниями и магией черного вуду, некоторые люди могут делать больше вещей для vfork() ребенка в Linux, но это требует большого внимания к деталям.

Итак, как вы можете видеть, есть много ограничений на то, что вы можете делать, когда делитесь памятью и возвращаете fork(): есть очень веская причина, почему создание потока обычно выполняется путем вызова функция .

1 голос
/ 03 июня 2011

Вы можете делать такие вещи с помощью openMP

Это не совсем так, но процесс создания потоков выполняется автоматически, и есть механизмы для синхронизации и связи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...