Как к mmap стек для клона () системный вызов на Linux?

Возможно, необходимо рассмотреть использование HashSet.

Из ссылки MSDN:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        HashSet evenNumbers = new HashSet();
        HashSet oddNumbers = new HashSet();

        for (int i = 0; i < 5; i++)
        {
            // Populate numbers with just even numbers.
            evenNumbers.Add(i * 2);

            // Populate oddNumbers with just odd numbers.
            oddNumbers.Add((i * 2) + 1);
        }

        Console.Write("evenNumbers contains {0} elements: ", evenNumbers.Count);
        DisplaySet(evenNumbers);

        Console.Write("oddNumbers contains {0} elements: ", oddNumbers.Count);
        DisplaySet(oddNumbers);

        // Create a new HashSet populated with even numbers.
        HashSet numbers = new HashSet(evenNumbers);
        Console.WriteLine("numbers UnionWith oddNumbers...");
        numbers.UnionWith(oddNumbers);

        Console.Write("numbers contains {0} elements: ", numbers.Count);
        DisplaySet(numbers);
    }

    private static void DisplaySet(HashSet set)
    {
        Console.Write("{");
        foreach (int i in set)
        {
            Console.Write(" {0}", i);
        }
        Console.WriteLine(" }");
    }
}

/* This example produces output similar to the following:
 * evenNumbers contains 5 elements: { 0 2 4 6 8 }
 * oddNumbers contains 5 elements: { 1 3 5 7 9 }
 * numbers UnionWith oddNumbers...
 * numbers contains 10 elements: { 0 2 4 6 8 1 3 5 7 9 }
 */

10
задан Joseph Garvin 4 July 2009 в 23:30
поделиться

5 ответов

Джозеф, в ответ на ваш последний вопрос:

Когда пользователь создает «нормальный» новый процесс, который выполняется fork (). В этом случае ядру вообще не нужно беспокоиться о создании нового стека, потому что новый процесс является полной копией старого, вплоть до стека.

Если пользователь заменяет текущий запущенный процесс используя exec (), тогда ядру действительно нужно создать новый стек - но в этом случае это легко, потому что оно начинает с чистого листа. exec () стирает пространство памяти процесса и повторно инициализирует его, поэтому ядро ​​может сказать «после exec (), потому что тогда наши два процесса будут топать друг друга в стеке. Ядро также не может просто поместить его в место по умолчанию (как это делает exec ()), потому что это место уже занято в этом пространстве памяти. Единственное решение - позволить вызывающему процессу найти для него место, что он и делает.

потому что тогда наши два процесса будут топать друг друга в стеке. Ядро также не может просто поместить его в место по умолчанию (как это делает exec ()), потому что это место уже занято в этом пространстве памяти. Единственное решение - позволить вызывающему процессу найти для него место, что он и делает.

2
ответ дан 3 December 2019 в 23:14
поделиться

Вам нужен флаг MAP_ANONYMOUS для mmap. И MAP_GROWSDOWN, поскольку вы хотите использовать его в качестве стека.

Что-то вроде:

void *stack = mmap(NULL,initial_stacksize,PROT_WRITE|PROT_READ,MAP_PRIVATE|MAP_GROWSDOWN|MAP_ANONYMOUS,-1,0);

Дополнительную информацию см. На странице руководства mmap. И помните, клонирование - это концепция низкого уровня, которую вы не должны использовать, если вам действительно не нужно то, что она предлагает. И он предлагает много возможностей управления - например, настройку собственного стека - на случай, если вы захотите немного обмануть (например, сделать стек доступным во всех связанных процессах). Если у вас нет веских причин использовать clone, используйте fork или pthreads.

5
ответ дан 3 December 2019 в 23:14
поделиться

mmap - это больше, чем просто отображение файла в памяти. Фактически, некоторые реализации malloc будут использовать mmap для больших распределений. Если вы прочтете прекрасную страницу руководства, вы заметите флаг MAP_ANONYMOUS, и вы увидите, что вам совсем не нужно предоставлять дескриптор файла.

Что касается того, почему ядро ​​не может просто «найти кучу бесплатных memory ", ну, если вы хотите, чтобы кто-то делал эту работу за вас, используйте вместо него fork или pthreads.

0
ответ дан 3 December 2019 в 23:14
поделиться

Note that the clone system call doesn't take an argument for the stack location. It actually works just like fork. It's just the glibc wrapper which takes that argument.

0
ответ дан 3 December 2019 в 23:14
поделиться

Вот код, который отображает область стека и инструктирует системный вызов clone использовать эту область в качестве стека.

#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <sched.h>

int execute_clone(void *arg)
{
    printf("\nclone function Executed....Sleeping\n");
    fflush(stdout);
    return 0;
}

int main()
{
    void *ptr;
    int rc;
    void *start =(void *) 0x0000010000000000;
    size_t len = 0x0000000000200000;

    ptr = mmap(start, len, PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED|MAP_GROWSDOWN, 0, 0);
    if(ptr == (void *)-1) 
    {
        perror("\nmmap failed");
    }

    rc = clone(&execute_clone, ptr + len, CLONE_VM, NULL);

    if(rc <= 0) 
    {
        perror("\nClone() failed");
    }
}
1
ответ дан 3 December 2019 в 23:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: