Maison Opération et maintenance exploitation et maintenance Linux Analyse de code d'exemple de programmation multithread Linux

Analyse de code d'exemple de programmation multithread Linux

May 26, 2023 pm 10:04 PM
linux

Prenons d'abord un exemple. Nous créons deux threads pour incrémenter un nombre. Peut-être que cet exemple n’a aucune valeur pratique, mais avec un léger changement, nous pouvons l’utiliser ailleurs.

Code :

/*thread_example.c : c multiple thread programming in linux
 *author : falcon
 *e-mail : tunzhj03@st.lzu.edu.cn
 */
#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#define max 10

pthread_t thread[2];
pthread_mutex_t mut;
int number=0, i;

void *thread1()
{
    printf ("thread1 : i&#39;m thread 1/n");

    for (i = 0; i < max; i++)
    {
        printf("thread1 : number = %d/n",number);
        pthread_mutex_lock(&mut);
            number++;
        pthread_mutex_unlock(&mut);
        sleep(2);
    }


    printf("thread1 :主函数在等我完成任务吗?/n");
    pthread_exit(null);
}

void *thread2()
{
    printf("thread2 : i&#39;m thread 2/n");

    for (i = 0; i < max; i++)
    {
        printf("thread2 : number = %d/n",number);
        pthread_mutex_lock(&mut);
            number++;
        pthread_mutex_unlock(&mut);
        sleep(3);
    }


    printf("thread2 :主函数在等我完成任务吗?/n");
    pthread_exit(null);
}

void thread_create(void)
{
    int temp;
    memset(&thread, 0, sizeof(thread));     //comment1
    /*创建线程*/
    if((temp = pthread_create(&thread[0], null, thread1, null)) != 0) //comment2   
        printf("线程1创建失败!/n");
    else
        printf("线程1被创建/n");

    if((temp = pthread_create(&thread[1], null, thread2, null)) != 0) //comment3
        printf("线程2创建失败");
    else
        printf("线程2被创建/n");
}

void thread_wait(void)
{
    /*等待线程结束*/
    if(thread[0] !=0)      {       //comment4          pthread_join(thread[0],null);
        printf("线程1已经结束/n");
     }
    if(thread[1] !=0)      {         //comment5        pthread_join(thread[1],null);
        printf("线程2已经结束/n");
     }
}

int main()
{
    /*用默认属性初始化互斥锁*/
    pthread_mutex_init(&mut,null);

    printf("我是主函数哦,我正在创建线程,呵呵/n");
    thread_create();
    printf("我是主函数哦,我正在等待线程完成任务阿,呵呵/n");
    thread_wait();

    return 0;
}
Copier après la connexion

Compilons-le et exécutons-le d'abord

Citation :

falcon@falcon:~/program/c/code/ftp$ gcc -lpthread -o thread_example thread_example.c
falcon@falcon:~/program/c/code/ftp$ ./thread_example
我是主函数哦,我正在创建线程,呵呵
线程1被创建
线程2被创建
我是主函数哦,我正在等待线程完成任务阿,呵呵
thread1 : i&#39;m thread 1
thread1 : number = 0
thread2 : i&#39;m thread 2
thread2 : number = 1
thread1 : number = 2
thread2 : number = 3
thread1 : number = 4
thread2 : number = 5
thread1 : number = 6
thread1 : number = 7
thread2 : number = 8
thread1 : number = 9
thread2 : number = 10
thread1 :主函数在等我完成任务吗?
线程1已经结束
thread2 :主函数在等我完成任务吗?
线程2已经结束
Copier après la connexion

Dans l'exemple de code Les commentaires devrait être plus clair. Je vais maintenant citer plusieurs fonctions et variables mentionnées ci-dessus sur Internet.

Citation :

Opérations liées aux threads

一pthread_t

pthread_t est dans le fichier d'en-tête /usr/include/ bits/ Défini dans pthreadtypes.h :
Typedef unsigned long int pthread_t
C'est l'identifiant d'un thread.

二pthread_create

La fonction pthread_create permet de créer un thread. Son prototype est :
extern int pthread_create __p ((pthread_t *__thread, __const pthread_attr_t *__attr ,
void *(*__start_routine) (void *), void *__arg));
Le premier paramètre est un pointeur vers l'identifiant du thread, le deuxième paramètre est utilisé pour définir les attributs du thread et le troisième paramètre Le paramètre est l'adresse de départ du thread exécutant la fonction, et le dernier paramètre est le paramètre de la fonction en cours d'exécution. Ici, notre thread de fonction ne nécessite pas de paramètres, donc le dernier paramètre est défini sur un pointeur nul. Nous définissons également le deuxième paramètre sur un pointeur nul, qui générera un thread avec les attributs par défaut. Nous expliquerons le paramétrage et la modification des attributs du thread dans la section suivante. Lorsque le thread est créé avec succès, la fonction renvoie 0. Si ce n'est pas 0, la création du thread échoue. Les codes de retour d'erreur courants sont eagain et einval. Le premier signifie que le système restreint la création de nouveaux threads, par exemple, le nombre de threads est trop élevé ; le second signifie que la valeur de l'attribut du thread représentée par le deuxième paramètre est illégale. Une fois le thread créé avec succès, le thread nouvellement créé exécute la fonction déterminée par le paramètre trois et le paramètre quatre, et le thread d'origine continue d'exécuter la ligne de code suivante.

三 pthread_join pthread_exit
 
La fonction pthread_join permet d'attendre la fin d'un fil. Le prototype de la fonction est :
extern int pthread_join __p ((pthread_t __th, void **__thread_return));
Le premier paramètre est l'identifiant du thread à attendre, et le deuxième paramètre est un identifiant défini par l'utilisateur. pointeur , qui peut être utilisé pour stocker la valeur de retour du thread en attente. Cette fonction est une fonction bloquant les threads. La fonction qui l'appelle attendra la fin du thread en attente. Au retour de la fonction, les ressources du thread en attente sont récupérées. Il existe deux manières de terminer un thread. L'une est comme dans notre exemple ci-dessus. Lorsque la fonction se termine, le thread qui l'a appelée se termine également via la fonction pthread_exit. Son prototype de fonction est :
extern void pthread_exit __p ((void *__retval)) __attribute__ ((__noreturn__));
Le seul paramètre est le code retour de la fonction, tant que le deuxième paramètre thread_return in pthread_join Non nul, cette valeur sera transmise à thread_return. La dernière chose à noter est qu'un thread ne peut pas être attendu par plusieurs threads, sinon le premier thread à recevoir le signal revient avec succès et les threads restants qui appellent pthread_join renvoient le code d'erreur esrch.
Dans cette section, nous avons écrit le fil de discussion le plus simple et maîtrisé les trois fonctions les plus couramment utilisées pthread_create, pthread_join et pthread_exit. Examinons ensuite quelques propriétés courantes des threads et comment les définir.

Mutex lock Related

Le verrouillage Mutex est utilisé pour garantir qu'un seul thread exécute un morceau de code sur une période donnée.

一 pthread_mutex_init

La fonction pthread_mutex_init est utilisée pour générer un verrou mutex. Le paramètre null indique que les propriétés par défaut sont utilisées. Si vous devez déclarer un mutex pour un attribut spécifique, vous devez appeler la fonction pthread_mutexattr_init. La fonction pthread_mutexattr_setpshared et la fonction pthread_mutexattr_settype sont utilisées pour définir les attributs de verrouillage mutex. La fonction précédente définit l'attribut pshared, qui a deux valeurs, pthread_process_private et pthread_process_shared. Le premier est utilisé pour synchroniser les threads dans différents processus, et le second est utilisé pour synchroniser différents threads dans ce processus. Dans l'exemple ci-dessus, nous utilisons l'attribut par défaut pthread_process_private. Ce dernier est utilisé pour définir le type de verrouillage mutex. Les types facultatifs sont pthread_mutex_normal, pthread_mutex_errorcheck, pthread_mutex_recursive et pthread _mutex_default. Ils définissent respectivement différents mécanismes de listing et de déverrouillage. Dans des circonstances normales, le dernier attribut par défaut est sélectionné.

二pthread_mutex_lock pthread_mutex_unlock pthread_delay_np

L'instruction pthread_mutex_lock commence à se verrouiller avec un mutex, et le code suivant est verrouillé jusqu'à ce que pthread_mutex_unlock soit appelé, c'est-à-dire qu'il ne peut être verrouillé que par un en même temps Exécution de l'appel de thread. Lorsqu'un thread s'exécute sur pthread_mutex_lock, si le verrou est utilisé par un autre thread à ce moment-là, le thread est bloqué, c'est-à-dire que le programme attendra qu'un autre thread libère le verrou mutex.

Attention :

1 Il convient de noter que les deux mises en veille ci-dessus ne sont pas seulement à des fins de démonstration, mais également pour laisser le thread dormir pendant un certain temps, laisser le thread libérer le verrou mutex et attendre qu'un autre thread l'utilise verrouillage. Ce problème est expliqué dans la référence 1 ci-dessous. Cependant, il ne semble pas y avoir de fonction pthread_delay_np sous Linux (je l'ai essayée et il m'a été demandé qu'il n'y avait aucune référence à la fonction définie), j'ai donc utilisé sleep à la place. Cependant, une autre méthode est donnée dans la référence 2, qui semble le faire. être remplacé par pthread_cond_timedwait , ce qui donne un moyen d'y parvenir.

2 Veuillez faire attention aux commentaires 1 à 5 à l'intérieur, c'est là que le problème m'a pris plusieurs heures à découvrir.
S'il n'y a pas de commentaire1, comment4 et comment5, cela provoquera une erreur de segmentation lors de pthread_join. De plus, les commentaires2 et comment3 ci-dessus en sont la cause première, alors n'oubliez pas d'écrire l'intégralité du code. Étant donné que le thread ci-dessus peut ne pas être créé avec succès, il est impossible d'attendre la fin de ce thread et une erreur de segmentation se produit (une zone mémoire inconnue est accédée) lors de l'utilisation de pthread_join. De plus, lorsque vous utilisez memset, vous devez inclure le fichier d'en-tête string.h

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Quatre façons d'implémenter le multithreading dans le langage C Quatre façons d'implémenter le multithreading dans le langage C Apr 03, 2025 pm 03:00 PM

Le multithreading dans la langue peut considérablement améliorer l'efficacité du programme. Il existe quatre façons principales d'implémenter le multithreading dans le langage C: créer des processus indépendants: créer plusieurs processus en cours d'exécution indépendante, chaque processus a son propre espace mémoire. Pseudo-Multithreading: Créez plusieurs flux d'exécution dans un processus qui partagent le même espace mémoire et exécutent alternativement. Bibliothèque multi-thread: Utilisez des bibliothèques multi-threades telles que PTHEADS pour créer et gérer des threads, en fournissant des fonctions de fonctionnement de thread riches. Coroutine: une implémentation multi-thread légère qui divise les tâches en petites sous-tâches et les exécute tour à tour.

Comment ouvrir web.xml Comment ouvrir web.xml Apr 03, 2025 am 06:51 AM

Pour ouvrir un fichier web.xml, vous pouvez utiliser les méthodes suivantes: Utilisez un éditeur de texte (tel que le bloc-notes ou TextEdit) pour modifier les commandes à l'aide d'un environnement de développement intégré (tel qu'Eclipse ou NetBeans) (Windows: Notepad web.xml; Mac / Linux: Open -A TextEdit web.xml)

L'interprète Python peut-il être supprimé dans le système Linux? L'interprète Python peut-il être supprimé dans le système Linux? Apr 02, 2025 am 07:00 AM

En ce qui concerne le problème de la suppression de l'interpréteur Python qui est livré avec des systèmes Linux, de nombreuses distributions Linux préinstalleront l'interpréteur Python lors de l'installation, et il n'utilise pas le gestionnaire de packages ...

À quoi sert le mieux le Linux? À quoi sert le mieux le Linux? Apr 03, 2025 am 12:11 AM

Linux est mieux utilisé comme gestion de serveurs, systèmes intégrés et environnements de bureau. 1) Dans la gestion des serveurs, Linux est utilisé pour héberger des sites Web, des bases de données et des applications, assurant la stabilité et la fiabilité. 2) Dans les systèmes intégrés, Linux est largement utilisé dans les systèmes électroniques intelligents et automobiles en raison de sa flexibilité et de sa stabilité. 3) Dans l'environnement de bureau, Linux fournit des applications riches et des performances efficaces.

Comment est la compatibilité Debian Hadoop Comment est la compatibilité Debian Hadoop Apr 02, 2025 am 08:42 AM

Debianlinux est connu pour sa stabilité et sa sécurité et est largement utilisé dans les environnements de serveur, de développement et de bureau. Bien qu'il y ait actuellement un manque d'instructions officielles sur la compatibilité directe avec Debian et Hadoop, cet article vous guidera sur la façon de déployer Hadoop sur votre système Debian. Exigences du système Debian: Avant de commencer la configuration de Hadoop, assurez-vous que votre système Debian répond aux exigences de fonctionnement minimales de Hadoop, qui comprend l'installation de l'environnement d'exécution Java (JRE) nécessaire et des packages Hadoop. Étapes de déploiement de Hadoop: Télécharger et unzip Hadoop: Téléchargez la version Hadoop dont vous avez besoin sur le site officiel d'Apachehadoop et résolvez-le

Dois-je installer un client Oracle lors de la connexion à une base de données Oracle à l'aide de Go? Dois-je installer un client Oracle lors de la connexion à une base de données Oracle à l'aide de Go? Apr 02, 2025 pm 03:48 PM

Dois-je installer un client Oracle lors de la connexion à une base de données Oracle à l'aide de Go? Lorsque vous développez GO, la connexion aux bases de données Oracle est une exigence commune ...

Debian Strings est-il compatible avec plusieurs navigateurs Debian Strings est-il compatible avec plusieurs navigateurs Apr 02, 2025 am 08:30 AM

"Debianstrings" n'est pas un terme standard, et sa signification spécifique n'est pas encore claire. Cet article ne peut pas commenter directement la compatibilité de son navigateur. Cependant, si "DebianStrings" fait référence à une application Web exécutée sur un système Debian, sa compatibilité du navigateur dépend de l'architecture technique de l'application elle-même. La plupart des applications Web modernes se sont engagées à compatibilité entre les navigateurs. Cela repose sur les normes Web suivantes et l'utilisation de technologies frontales bien compatibles (telles que HTML, CSS, JavaScript) et les technologies back-end (telles que PHP, Python, Node.js, etc.). Pour s'assurer que l'application est compatible avec plusieurs navigateurs, les développeurs doivent souvent effectuer des tests croisés et utiliser la réactivité

See all articles