Linux - Regardez autour de copy_mm ()

Tux_Enhanced.svg.png

Aperçu

Je l'ai lu pour avoir une idée de la différence entre multi-processus / thread, alors je l'ai résumé. Lisez 5.4 pour voir la version torvalds/linux

Threads et processus sous Linux

Fil vert / fil natif

Threads planifiés par des machines virtuelles, pas par le système d'exploitation. Émulez un environnement multithread indépendamment des fonctionnalités du système d'exploitation.

Le planificateur du système d'exploitation planifie l'exécution des threads (Peut être affiché avec -L dans la commande ps)

(A part) L'histoire du modèle de fil

Le thread M: N est un modèle de thread asymétrique dans lequel le thread du noyau est M et le thread utilisateur est N. Fonctionne en mappant plusieurs threads du noyau à plusieurs threads utilisateur Il semble que Golang l'utilise et le coût du changement est très faible.

J'ai regardé la source du noyau

Fondamentalement, fork (2) et pthred_create () appellent en interne do_fork (). clone appelle do_fork après son appel. Il semble que la différence entre la création de processus et de thread se distingue par la différence dans l'indicateur lors de l'appel de cette do_fork ().

long sys_clone(unsigned long clone_flags, unsigned long newsp,
	       void __user *parent_tid, void __user *child_tid)
{
	long ret;

	if (!newsp)
		newsp = UPT_SP(&current->thread.regs.regs);
	current->thread.forking = 1;
	ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
		      child_tid);
	current->thread.forking = 0;
	return ret;
}

Aperçu du flux de traitement

do_fork()_do_fork()copy_process()copy_mm()dup_mmap () (Si ce n'est pas LWP, traitez la vache ci-dessous) ⑥ copy_page_range()copy_one_pte () Copier la zone vm d'une tâche à une autre

static int copy_mm(unsigned long clone_flags, struct task_struct *tsk)
{
    struct mm_struct *mm, *oldmm;
    int retval;

    tsk->min_flt = tsk->maj_flt = 0;
    tsk->nvcsw = tsk->nivcsw = 0;
#ifdef CONFIG_DETECT_HUNG_TASK
    tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
    tsk->last_switch_time = 0;
#endif

    tsk->mm = NULL;
    tsk->active_mm = NULL;

    oldmm = current->mm;
    if (!oldmm)
        return 0;

    //Initialisation de l'entrée vmacache
    vmacache_flush(tsk);

    // CLONE_Si une machine virtuelle est configurée, le processus appelant et les processus enfants
    //Il fonctionne dans le même espace mémoire.
    if (clone_flags & CLONE_VM) {
        mmget(oldmm);
        //Définir mm de processus parent sur enfant et bon_À mm
        mm = oldmm;
        goto good_mm;
    }

    retval = -ENOMEM;
    // CLONE_Dupliquer la structure mm existante si la VM n'est pas définie
    mm = dup_mm(tsk, current->mm);
    if (!mm)
        goto fail_nomem;

good_mm:
    tsk->mm = mm;
    tsk->active_mm = mm;
    return 0;

fail_nomem:
    return retval;
}

Le processus de copy_mm appelé après clone (2). Il s'avère que si CLONE_VM est défini (indicateur lors de la création du thread), il partage une adresse avec le processus parent. https://linuxjm.osdn.jp/html/LDP_man-pages/man2/clone.2.html

static struct mm_struct *dup_mm(struct task_struct *tsk,
                struct mm_struct *oldmm)
{
    struct mm_struct *mm;
    int err;

    mm = allocate_mm();
    if (!mm)
        goto fail_nomem;

    //Copiez la mémoire du processus parent dans le processus généré
    memcpy(mm, oldmm, sizeof(*mm));

    if (!mm_init(mm, tsk, mm->user_ns))
        goto fail_nomem;

    err = dup_mmap(mm, oldmm);
    if (err)
        goto free_pt;

    mm->hiwater_rss = get_mm_rss(mm);
    mm->hiwater_vm = mm->total_vm;

    if (mm->binfmt && !try_module_get(mm->binfmt->module))
        goto free_pt;

    return mm;

free_pt:
    /* don't put binfmt in mmput, we haven't got module yet */
    mm->binfmt = NULL;
    mm_init_owner(mm, NULL);
    mmput(mm);

fail_nomem:
    return NULL;
}

Le traitement principal de copy_mm. Si CLONE_VM (thread) est défini au moment du traitement précédent, ce traitement n'est pas effectué. Les threads peuvent accéder aux données à partir desquelles ils ont été créés. Dans le cas d'un processus, le processus de copie de la mémoire du processus parent est exécuté. (À décrire plus tard.)

Supplément

mm_struct --Structure qui gère les informations d'espace d'adressage

article Aperçu
mmap vm_area_Tenez le début de la structure
mm_rb Rouge pour une recherche rapide de la zone mémoire-Tenez un arbre noir
mmap_cache Référence de la mémoire brute locale(locality)Pour accélérer en profitant de
mm_count Compteur de référence pour cette structure. Si 0, aucun objet n'est pointé
mm_list mm_struct Champ de création d'une liste de structures
start_code, end_code Adresses de début et de fin du segment de texte
start_brk, brk Adresses de début et de fin du tas
start_stack Adresse de départ de la pile

référence

Recommended Posts

Linux - Regardez autour de copy_mm ()
Jouez avec les partitions Linux ~ Suite ~