Passage d'une structure en paramètre d'un thread

Résolu
ulukai44 Messages postés 4 Date d'inscription mercredi 17 octobre 2007 Statut Membre Dernière intervention 2 novembre 2007 - 29 oct. 2007 à 14:54
ulukai44 Messages postés 4 Date d'inscription mercredi 17 octobre 2007 Statut Membre Dernière intervention 2 novembre 2007 - 2 nov. 2007 à 13:20
Salut,

En fait, je démarre plusieurs thread qui vont éxécuter une fonction :


(la fonction reçoit en paramètre une structure)





struct partie { int var1; char var2[10] }

main {
...
    pthread_t tabThread[max];
    struct partie tableau[max];

    for (i=0; i<max; i++) {
        pthread_create(&tabThread[i], NULL, fonction, &tableau[i]);
    }
...
}

Je souhaite passer l'adresse de la structure "tableau[i]" à chaque thread.
Dans la fonction, mon problème est que je n'arrive pas à récupérer cette structure "tableau[i]" ?

void *fonction (void *p_data)
{
...
    struct partie * t = (struct partie *) p_data; // problème ici surement

    t.var1 = 3;
  ...
}

dans la compilation j'ai l'erreur pour la fonction : "request for member var1 in something not a structure or union"




merci d'avance;)

mat

6 réponses

DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
29 oct. 2007 à 15:06
Tu définies un pointeur et tu  accèes de la sorte  t.var1 = 3 ????

Essaye plutot t->var1 = 3;

Shell
3
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
29 oct. 2007 à 15:08
Autre remarque pendant que j'y pense, pourquoi ne passes tu pas directement le param de type partie, ca t'evite de faire un cast juste après.
Puis pas besoin de créer une nouvelle valeur en local, tu peux directement de te servir de ton paramètre.

Shell
3
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
29 oct. 2007 à 17:21
Oui il y a surement un moyen, a tio de voir lequel car je ne connais pas ton code.
Je dirais de déclarer un tableau d'entier qui stock la valeur de i pour chaque thread lancé. Ainsi ton thread sera capable de retrouvé la valeur de i qui va bien.... A essayer :)

Shell
3
ulukai44 Messages postés 4 Date d'inscription mercredi 17 octobre 2007 Statut Membre Dernière intervention 2 novembre 2007
2 nov. 2007 à 13:20
personne ne peut m'aider pour mon problème
mat
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ulukai44 Messages postés 4 Date d'inscription mercredi 17 octobre 2007 Statut Membre Dernière intervention 2 novembre 2007
29 oct. 2007 à 16:31
ok merci, plus d'erreur maintenant;)

j'ai un autre problème :

pour chaque création de thread

;  le i est modifié quand il y a plusieurs thread en même temps;
et donc je ne peux plus accèder

(ou modifier)

dans ma fonction à

tableau[1].var1 (i est à 1) quand

par exemple

un deuxième thread est lancé (le i est passé à 2);

il y a t'il un moyen de conserver le i du 1er thread ? celui du second, etc?

mat
0
ulukai44 Messages postés 4 Date d'inscription mercredi 17 octobre 2007 Statut Membre Dernière intervention 2 novembre 2007
31 oct. 2007 à 16:24
Merci ta réponse marche. En fait j'ai un autre problème dans mon code :

Je programme une application client  / serveur en C (en utilisant les threads dans mon fichier serveur.c)

Je lance mon fichier serveur.
Je lance un client ca fonctionne, il me demande si je veux continuer, je taper 1.
Je lance un autre client, et pour ce dernier client ca fonctionne, je taper 1 aussi.
Mais si je reviens à la fenêtre du premier client dans le terminal et que je retape 1 pour continuer encore ba il bloque.

J'ai passé qq heures sur le code; et j'vois pas pouquoi. si vous avez des solutions merci.

En fait le plus récent client lancé marche et les anciens ne marchent plus en même temps.

Ca vient peut être des threads

Voilà mon code :merci d'avance

/***************************************************************************

   Nom du fichier : serveur.c

****************************************************************************/
/
#include <stdlib.h>
#include <stdio.h>
#include <linux/types.h>   /*pour les sockets*/
#include <sys/socket.h>
#include <netdb.h>         /*pour hostent,servent*/
#include <string.h>        /*pour bcopy, ... */

#include /*pour thread*/

#define MAXDATASIZE 256

int sd,            /*descripteur de socket*/
    nsd;       /*[nouveau] descripteur de socket */
              

/*-------------------------------------------------*/
void *fonction (void *p_data)
{

int rec;
int continuer = 1;
char bufrecv[MAXDATASIZE];
char bufsend[MAXDATASIZE];

while (continuer == 1) {
   
    strcpy(bufsend, "\n\nVoulez vous continuer taper 0 (non) / 1 (oui) ? ");

    if (write(nsd, bufsend , sizeof(bufsend)) < 0) perror("write");       

    if ((rec= read(nsd, bufrecv, sizeof(bufrecv))) >0) {
        bufrecv[rec] = '\0';
        sscanf(bufrecv, "%d", &continuer);
    }

}

/*fermeture du socket d'échange*/
close(nsd);

pthread_exit(NULL);
return NULL;

}
/*-------------------------------------------------*/

main(argc, argv)
int argc;
char **argv;
{

int ladcour;       /*longeur d'adresse courante d'un client*/

struct sockaddr_in adsock,  /*structure d'adresse locale*/
       adclcour;    /*adresse client courant*/
struct hostent *hptr;       /*les infos recuperee sur la machine hote*/
struct servent *sptr;       /*les infos recuperee sur le service de la machine*/
char machine[MAXDATASIZE];     /*nom de la machine locale*/
char *prog;                 /*nom du programme*/

prog=argv[0];               /*recuperation du nom du programme*/
gethostname(machine, MAXDATASIZE); /*recuperation du nom de la machine*/

if ((hptr=gethostbyname(machine))==NULL)
{
perror(">> Machine inconnue");
exit(1);
}

bcopy((char *)hptr->h_addr,
      (char *)&adsock.sin_addr,
      hptr->h_length);
adsock.sin_family=hptr->h_addrtype;   /*ou bien AF_INET*/
adsock.sin_addr.s_addr=INADDR_ANY;    /*ou bien AF_INET*/

if ((sptr=getservbyname("irc", "tcp"))==NULL)
{
  perror(">> Probleme de recuperation des infos sur le service");
  exit(1);
}

adsock.sin_port= htons(sptr->s_port);

if ((sd=socket(AF_INET,SOCK_STREAM, 0))<0)
{
  perror(">> Probleme de creation du socket");
  exit(1);
}

int j = 1;
if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &j, sizeof(j))<0)
{
printf("Can't set SO_REUSEADDR");
exit(1);
}

if ((bind(sd,&adsock, sizeof(adsock)))<0)
{
  perror(">> Probleme avec le binding");
  exit(1);
}
   
printf("%d = Num-Port\n", ntohs(adsock.sin_port)); /*juste une trace*/
printf("Creation de la socket et attente d'une connexion...\n");   

listen(sd,5);

pthread_t t;
int code;

/*attente des connexions et traitement*/
while (1) {

    srand (time (NULL));

    ladcour=sizeof(adclcour);
    /*adclcour sera renseigne par accept via les infos du connect*/
    /* nsd est une socket d'échange que l'on doit fermer dans la boucle while(1){}*/
    if ((nsd = accept(sd, &adclcour, &ladcour))<0) {
        perror(">> Probleme sur l'accept");
              exit(1);
    }

    /*création des threads*/
    code = pthread_create(&t, NULL, fonction, NULL);
    if (code < 0) perror("Creation du thread");

}

} /*du main*/

/************************************************************************

   Nom du fichier : client.c

************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <linux/types.h>   /*pour les sockets*/
#include <sys/socket.h>
#include <netdb.h>         /*pour hostent,servent*/
#include <string.h>        /*pour bcopy, ... */

#define MAXDATASIZE 256

int main(argc, argv)
int argc;
char **argv;
{
int sd,             /* descripteur de socket */
    lenght_buffer;            /* longueur d'un buffer utilisé */
struct sockaddr_in adsock;  /* structure d'adresse locale */
struct hostent *hptr;       /* les infos recuperee sur la machine hote */
struct servent *sptr;       /* les infos recuperee sur le service de la machine */

char buf[MAXDATASIZE];
char  *prog; /* nom du programme */
char *host; /* nom de la machine distance */

prog = argv[0];
printf("\nCode client> %s\n", prog);

if (argc != 2)
 {
perror(">> Il faut deux arguments au programme");
exit(1);
 }

host = argv[1];
printf("Code client --> machine = %s \n", host);
if ((hptr gethostbyname(host)) NULL)
 {
perror(">> Pb pour la recup des infos du host");
exit(1);   
 }

bcopy((char *)hptr->h_addr,
      (char *)&adsock.sin_addr,
      hptr->h_length);
adsock.sin_family= AF_INET;
if ((sptr getservbyname("irc", "tcp")) NULL)
  {
    perror("Pb pour la recup des infos sur le service");
    exit(1);
  }
adsock.sin_port = htons(sptr->s_port);

printf("Code client--> numport = %d \n", ntohs(sptr->s_port));

if ((sd=socket(AF_INET,SOCK_STREAM, 0))<0)
{
  perror(">> Probleme de creation du socket");
  exit(1);
}

if ((connect(sd, &adsock, sizeof(adsock)))<0)
  {
  perror(">> Pb de connection");
  exit(1);   
  }

char bufrecv[MAXDATASIZE];
char bufsend[MAXDATASIZE];
int rec;

int continuer = 1;

while(continuer == 1) {

    if ((rec= read(sd, bufrecv, sizeof(bufrecv))) >0) {
        bufrecv[rec] = '\0';
        printf("%s", bufrecv);
    }

    scanf("%s", bufsend);
   
    if (write(sd, bufsend , sizeof(bufsend)) < 0) perror("write");       
    sscanf(bufsend,"%d",&continuer);

}

close(sd);
exit(0);

} /*du main*/
0
Rejoignez-nous