【问题标题】:How can i use an array of threads from process in C如何在 C 中使用进程中的线程数组
【发布时间】:2020-10-09 03:07:15
【问题描述】:

这是我关于机场结构的项目。我做了两个进程(每种飞机一个),每个进程都在做几个线程(一个线程是一架飞机)。

每个线程都运行 Pilot 函数,该函数将 structureVol(数据结构)作为输入并执行以下操作:

  • 离开功能(等到关键资源空闲后再拿走)
  • 等待(模拟旅行)
  • 到达功能(与出发功能相同)
  • 杀死线程

我不明白为什么脚本运行时没有错误并且几乎没有返回任何内容。 经过多次尝试(使用printf("something")),我发现脚本没有使用案例0,但typeheavy和typelight返回0。

我还发现它只在初始化一个线程而不是它的数组时起作用。

工作了几个小时后,我不认识遮阳篷了。

请原谅我的英语错误。

非常感谢。

#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>

pthread_mutex_t mutexPisteCourte = PTHREAD_MUTEX_INITIALIZER; //Short airplane landing strip mutex
pthread_mutex_t mutexPisteLongue = PTHREAD_MUTEX_INITIALIZER; //Long airplane landing strip mutex

#define tempsPiste 5    // Temps passé sur une piste (décoller et attérir) //Time on landing strip
#define tempsAeroport 5 // Temps max passé dans un aéroport // Time in a airport
#define tempsFrance 10  //Temps max de trajet en France // Time to travel through France
#define tempsEurope 25  //Temps max de trajet en Europe // Time to travel through Europe
#define nbAvionsLourd 5
#define nbAvionsLeger 2

//Prototypes
void attente(); // Wait function
void depart(int, int); //departure function
void arrivee(int, int); //arrival function
void affichage(int, char*); //display function
void *Pilote(void *); //Pilot function

//Structure représentant les données de vol //Structure were data are stored (id flight, type, destination and so on)
typedef struct structureVol
{
    long id;
    long type;
    long destination;
}structureVol;

                        /*----------------*/
                        /* -- Fonctions --*/
                        /*----------------*/

void depart(int i,int j) //departure function
{
    printf("Depart pris en compte"); //Test
    if (j==0)
    {
        pthread_mutex_lock(&mutexPisteCourte);
        attente(tempsPiste);
        pthread_mutex_unlock(&mutexPisteCourte);
    }
    if (j==1)
    {
        pthread_mutex_lock(&mutexPisteLongue);
        attente(tempsPiste);
        pthread_mutex_unlock(&mutexPisteLongue);
    }
    else
    {
        printf("Erreur sur l'attribution piste décollage");
    }
    /* TO DO
    Indiquer la piste de départ
    Indiquer l'itinéraire normalisé
    Indiquer la route à suivre jusqu'à la sortie de l'espace controlé ou le premier
    point de report
    Donner l'heure de décolage et sa limite.
    Départs réalisés dans l'ordre dans lequel les avions sont prêt à décoller
    Dernière règle peut être déroger pour avoir un maximum de départs ainsi qu'un
    retard moyen le plus faible
    */
}

void arrivee(int i,int j) //arrival function
{
    printf("Arrivée prise en compte"); //test
    if (j==0)
    {
        pthread_mutex_lock(&mutexPisteCourte);
        attente(tempsPiste);
        pthread_mutex_unlock(&mutexPisteCourte);
    }
    if (j==1)
    {
        pthread_mutex_lock(&mutexPisteLongue);
        attente(tempsPiste);
        pthread_mutex_unlock(&mutexPisteLongue);
    }
    else
    {
        printf("Erreur sur l'attribution piste arrivée");
    }
    /* TO DO
    Indiquer l'itinéraire normalisé ou la description de la route à suivre 
    jusqu'au point d'approche initiale ou au repère d'attente, jusqu'à un point
    significatif ou jusqu'à l'entrée du circuit d'aerodrome, indiquer l'heure
    d'approche prévue en cas d'attente ou l'estimation de la durée d'attente prévue.
    */
}


void *Pilote (void *arg) //Pilot function
{
    structureVol *donnees =(structureVol *) arg;

    /*  Depart de l'avion   */
    printf("Début du thread");
    depart(donnees->id,donnees->type);
    fprintf(stderr,"\033[91m le vol %ld de type %ld a démarer \033[0m\n",donnees->id,donnees->type);
    /*  Voyage de l'avion   */
    attente(tempsFrance); //Avion en vol vers France
    attente(tempsAeroport); //Avion en stationnement dans un autre aéroport
    attente(tempsFrance); //Avion sur le retour de France
    /*  Arrivé de l'avion   */
    arrivee(donnees->id,donnees->type);
    fprintf(stderr,"\033[91m le vol %ld de type %ld s'est bien terminé \033[0m\n",donnees->id,donnees->type);
    pthread_exit(NULL); //Fin thread

}

void attente(int i) /* Fonction permettant d'attendre un temps aléatoire entre 1 et i */ // Wait a time between i and 1 second
{
    //Initialisation du générateur de nombres aléatoire utilisant le temps système comme référence
    srand(time(NULL));
    int temps=rand()%i+1;
    printf("Attente de %d secondes \n", temps); 
    sleep(temps);
}

void affichage(int i, char* texte) //display function
{
    #define COLONNE 10
    int k, Espace;
    Espace = i*COLONNE ;
    for (k=0; k<Espace; k++)
    {
        putchar(' ');
    }
    printf("%s\n",texte);
    fflush(stdout);
}

                            /*------------*/
                            /* -- Main -- */
                            /*------------*/

int main (void)
{
    int i = 0;
    int thr = 0;
    //int nbAvionsTotal = nbAvionsLeger + nbAvionsLourd;

    structureVol *donneesVol;

    //char *s1, *s2;

    int typeheavy;
    int typelight;

    pthread_t avionlourds[nbAvionsLourd];
    pthread_t avionleger[nbAvionsLeger];

    printf("  -----  Initialisation du programme  ----- \n\n");

    affichage(1,"     -- Piste légère --  -- Piste lourde --\n");
    affichage(2,"Test 1");
    affichage(4,"Test 2");

    switch(typeheavy = fork())
    {   

        case -1:        
            printf("Erreur dans la création processus avion lourd \n");
            break;

        case 0: /* Processus type l'avion lourd */

            printf("test_");
            printf("je suis le fils");
            for (i=0; i<nbAvionsLourd; i++)
            {
                printf("test2_");
                donneesVol-> id = i;
                donneesVol->type = 1;
                donneesVol->destination = 0;

                /*   --- Creation de un thread par avion ---   */
                thr=pthread_create(&avionlourds[i], NULL, Pilote, (void *) donneesVol);
                /*  Erreur de création thread  */            

                if (thr)
                {
                    printf("Erreur sur thread %d type avion lourd \n",i);
                }
                for (i=0; i<nbAvionsLourd; i++)
                {
                    pthread_join(avionlourds[i],NULL);
                }

            }

            exit(0);

        default: /* Controleur (poursuit le programme) */

            printf("Dans le default\n");
            wait(0);
            printf("wait passé\n");

    } 
    printf("dans le main\n");
    switch(typelight = fork())
    {
        case -1:
            printf("Erreur dans la création processus avion léger \n");
            break;

        case 0: /* Processus fils type l'avion léger */
            for (i=0; i<nbAvionsLeger; i++)
            {
                donneesVol->id = i;
                donneesVol->type = 0;
                donneesVol->destination = 0;

                /*   --- Creation de un thread par avion ---   */
                thr=pthread_create(&avionleger[i], NULL, Pilote, (void*) donneesVol);
                /*  Erreur de création thread  */  
                if (thr)
                {
                    printf("Erreur sur thread %d type avion léger \n",i);
                }
                for (i=0; i<nbAvionsLeger; i++)
                {
                    pthread_join(avionleger[i],NULL);
                }
                exit(0);

            }   


        default: /* Controleur (poursuit le programme) */
            wait(0);
            printf("wait passé\n");

    }

    printf("\n  -----        Fin du programme       ----- \n");
    return 0;
}

【问题讨论】:

  • 'donnesVol' 分配在哪里?您应该为每个线程分配一个。

标签: c multithreading operating-system


【解决方案1】:

您的代码中有两个错误,第一个是您应该在每个案例的末尾放置一个 break(或程序失败),第二个是 donneesVol 未初始化,您更正的代码是这样的:

#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>

pthread_mutex_t mutexPisteCourte = PTHREAD_MUTEX_INITIALIZER; //Short airplane landing strip mutex
pthread_mutex_t mutexPisteLongue = PTHREAD_MUTEX_INITIALIZER; //Long airplane landing strip mutex

#define tempsPiste 5    // Temps passé sur une piste (décoller et attérir) //Time on landing strip
#define tempsAeroport 5 // Temps max passé dans un aéroport // Time in a airport
#define tempsFrance 10  //Temps max de trajet en France // Time to travel through France
#define tempsEurope 25  //Temps max de trajet en Europe // Time to travel through Europe
#define nbAvionsLourd 5
#define nbAvionsLeger 2
#define BUF_SIZE 100

//Prototypes
void attente(); // Wait function
void depart(int, int); //departure function
void arrivee(int, int); //arrival function
void affichage(int, char*); //display function
void *Pilote(void *); //Pilot function

//Structure représentant les données de vol //Structure were data are stored (id flight, type, destination and so on)
typedef struct structureVol
{
    long id;
    long type;
    long destination;
}structureVol;

                        /*----------------*/
                        /* -- Fonctions --*/
                        /*----------------*/

void depart(int i,int j) //departure function
{
    printf("Depart pris en compte"); //Test
    if (j==0)
    {
        pthread_mutex_lock(&mutexPisteCourte);
        attente(tempsPiste);
        pthread_mutex_unlock(&mutexPisteCourte);
    }
    if (j==1)
    {
        pthread_mutex_lock(&mutexPisteLongue);
        attente(tempsPiste);
        pthread_mutex_unlock(&mutexPisteLongue);
    }
    else
    {
        printf("Erreur sur l'attribution piste décollage");
    }
    /* TO DO
    Indiquer la piste de départ
    Indiquer l'itinéraire normalisé
    Indiquer la route à suivre jusqu'à la sortie de l'espace controlé ou le premier
    point de report
    Donner l'heure de décolage et sa limite.
    Départs réalisés dans l'ordre dans lequel les avions sont prêt à décoller
    Dernière règle peut être déroger pour avoir un maximum de départs ainsi qu'un
    retard moyen le plus faible
    */
}

void arrivee(int i,int j) //arrival function
{
    printf("Arrivée prise en compte"); //test
    if (j==0)
    {
        pthread_mutex_lock(&mutexPisteCourte);
        attente(tempsPiste);
        pthread_mutex_unlock(&mutexPisteCourte);
    }
    if (j==1)
    {
        pthread_mutex_lock(&mutexPisteLongue);
        attente(tempsPiste);
        pthread_mutex_unlock(&mutexPisteLongue);
    }
    else
    {
        printf("Erreur sur l'attribution piste arrivée");
    }
    /* TO DO
    Indiquer l'itinéraire normalisé ou la description de la route à suivre
    jusqu'au point d'approche initiale ou au repère d'attente, jusqu'à un point
    significatif ou jusqu'à l'entrée du circuit d'aerodrome, indiquer l'heure
    d'approche prévue en cas d'attente ou l'estimation de la durée d'attente prévue.
    */
}


void *Pilote (void *arg) //Pilot function
{
    structureVol *donnees =(structureVol *) arg;

    /*  Depart de l'avion   */
    printf("Début du thread");
    depart(donnees->id,donnees->type);
    fprintf(stderr,"\033[91m le vol %ld de type %ld a démarer \033[0m\n",donnees->id,donnees->type);
    /*  Voyage de l'avion   */
    attente(tempsFrance); //Avion en vol vers France
    attente(tempsAeroport); //Avion en stationnement dans un autre aéroport
    attente(tempsFrance); //Avion sur le retour de France
    /*  Arrivé de l'avion   */
    arrivee(donnees->id,donnees->type);
    fprintf(stderr,"\033[91m le vol %ld de type %ld s'est bien terminé \033[0m\n",donnees->id,donnees->type);
    pthread_exit(NULL); //Fin thread

}

void attente(int i) /* Fonction permettant d'attendre un temps aléatoire entre 1 et i */ // Wait a time between i and 1 second
{
    //Initialisation du générateur de nombres aléatoire utilisant le temps système comme référence
    srand(time(NULL));
    int temps=rand()%i+1;
    printf("Attente de %d secondes \n", temps);
    sleep(temps);
}

void affichage(int i, char* texte) //display function
{
    #define COLONNE 10
    int k, Espace;
    Espace = i*COLONNE ;
    for (k=0; k<Espace; k++)
    {
        putchar(' ');
    }
    printf("%s\n",texte);
    fflush(stdout);
}

                            /*------------*/
                            /* -- Main -- */
                            /*------------*/

int main (void)
{
    int i = 0;
    int thr = 0;
    //int nbAvionsTotal = nbAvionsLeger + nbAvionsLourd;

    structureVol donneesVol[BUF_SIZE];

    //char *s1, *s2;

    int typeheavy;
    int typelight;

    pthread_t avionlourds[nbAvionsLourd];
    pthread_t avionleger[nbAvionsLeger];

    printf("  -----  Initialisation du programme  ----- \n\n");

    affichage(1,"     -- Piste légère --  -- Piste lourde --\n");
    affichage(2,"Test 1");
    affichage(4,"Test 2");

    switch(typeheavy = fork())
    {

        case -1:
            printf("Erreur dans la création processus avion lourd \n");
            break;

        case 0: /* Processus type l'avion lourd */

            printf("test_");
            printf("je suis le fils");
            for (i=0; i<nbAvionsLourd; i++)
            {
                printf("test2_");
                donneesVol-> id = i;
                donneesVol->type = 1;
                donneesVol->destination = 0;

                /*   --- Creation de un thread par avion ---   */
                thr=pthread_create(&avionlourds[i], NULL, Pilote, &donneesVol[i]);
                /*  Erreur de création thread  */

                if (thr)
                {
                    printf("Erreur sur thread %d type avion lourd \n",i);
                }
                for (i=0; i<nbAvionsLourd; i++)
                {
                    pthread_join(avionlourds[i],NULL);
                }

            }

            exit(0);

        default: /* Controleur (poursuit le programme) */

            printf("Dans le default\n");
            wait(0);
            printf("wait passé\n");

    }
    printf("dans le main\n");
    switch(typelight = fork())
    {
        case -1:
            printf("Erreur dans la création processus avion léger \n");
            break;

        case 0: /* Processus fils type l'avion léger */
            for (i=0; i<nbAvionsLeger; i++)
            {
                donneesVol->id = i;
                donneesVol->type = 0;
                donneesVol->destination = 0;

                /*   --- Creation de un thread par avion ---   */
                thr=pthread_create(&avionleger[i], NULL, Pilote, &donneesVol[i]);
                /*  Erreur de création thread  */
                if (thr)
                {
                    printf("Erreur sur thread %d type avion léger \n",i);
                }
                for (i=0; i<nbAvionsLeger; i++)
                {
                    pthread_join(avionleger[i],NULL);
                }
                exit(0);

            }
            break;

        default: /* Controleur (poursuit le programme) */
            wait(0);
            printf("wait passé\n");

    }

    printf("\n  -----        Fin du programme       ----- \n");
    return 0;
}

【讨论】:

  • 您忘记编辑 pthread_create 调用以接受 donnesVol 现在是结构数组。此外,无论如何,使用数组作为线程元素并不是一个好的设计,但无论如何 OP 都在这样做,我几乎不能用它来对付你:) 我会在线程创建循环中分配一个新结构并让线程空闲之前终止。
  • ...如果你用 'i' 索引 '(void *) donneesVol' 可能会这样,这样每个线程都会获得一个指向不同结构的指针:)
  • 我也搞砸了 - 使用 '@' 而不是 '&' 作为地址运算符。这就是使用多种语言时会发生的情况:) 我编辑了我的评论。
  • 谢谢大家,我开始编程了,所以会犯很多错误(我的意思是我没有你们的经验和技能)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-22
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
  • 2014-05-10
  • 1970-01-01
相关资源
最近更新 更多