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 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)
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.
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(¤t->thread.regs.regs);
current->thread.forking = 1;
ret = do_fork(clone_flags, newsp, ¤t->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.)
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 |