Passage d'une structure en paramètre d'un thread [Résolu]

ulukai44 4 Messages postés mercredi 17 octobre 2007Date d'inscription 2 novembre 2007 Dernière intervention - 29 oct. 2007 à 14:54 - Dernière réponse : ulukai44 4 Messages postés mercredi 17 octobre 2007Date d'inscription 2 novembre 2007 Dernière intervention
- 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
Afficher la suite 

6 réponses

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

Essaye plutot t->var1 = 3;

Shell
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de DeAtHCrAsH
DeAtHCrAsH 2674 Messages postés vendredi 25 janvier 2002Date d'inscription 6 février 2013 Dernière intervention - 29 oct. 2007 à 15:08
+3
Utile
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
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de DeAtHCrAsH
DeAtHCrAsH 2674 Messages postés vendredi 25 janvier 2002Date d'inscription 6 février 2013 Dernière intervention - 29 oct. 2007 à 17:21
+3
Utile
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
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de DeAtHCrAsH
ulukai44 4 Messages postés mercredi 17 octobre 2007Date d'inscription 2 novembre 2007 Dernière intervention - 2 nov. 2007 à 13:20
+3
Utile
personne ne peut m'aider pour mon problème
mat
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de ulukai44
ulukai44 4 Messages postés mercredi 17 octobre 2007Date d'inscription 2 novembre 2007 Dernière intervention - 29 oct. 2007 à 16:31
0
Utile
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
Commenter la réponse de ulukai44
ulukai44 4 Messages postés mercredi 17 octobre 2007Date d'inscription 2 novembre 2007 Dernière intervention - 31 oct. 2007 à 16:24
0
Utile
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*/
Commenter la réponse de ulukai44

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.