Newsgroup: it.comp.os.linux.development
Titolo: PThread

Ciao a tutti
qualcuno di voi ha mai usato i pthread sotto linux?
Ecco il mio problema:
ho due thread che devono accedere ad una variabile comune. L'accesso a
questa variabile è regolato tramite mutua esclusione
(pthread_mutex_lock(), pthread_mutex_unlock()). Ora, alla quinta volta
(sempre alla quinta volta!!!) che uno dei due thread esegue
pthread_mutex_lock() non la passa e salta tutto.
La cosa comincia a darmi sui nervi.
Spero che mi possiate aiutare.
Grazie.
Mattia.
P.S.: se necessario vi posso inviare il codice.

P.S.: se necessario vi posso inviare il codice.
Postalo qui sul ng.
--
  	Giuseppe "Cowo" Corbelli  -->>  Riding on Linux-2.2.16
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
  -<! Heavy Metal Or No Metal At All! Whimps And Posers Leave The Hall !>-
 	 			Manowar - Metal Warriors

 Postalo qui sul ng.
#include "mtypes.h"
void *ciclo_ping(void *arg)
{
 DATA *C=(DATA *)arg;
 ELEM volatile *puntal;
 void *retval;
 PARAM_IN *pi=(PARAM_IN *)malloc(sizeof(PARAM_IN));
 PARAM_OUT *po=(PARAM_OUT *)malloc(sizeof(PARAM_OUT));
 pthread_mutex_lock(C->lista_lock);
 puntal=C->t_lista;
 while (puntal)
 {
  pi->host=puntal->ind;
  pi->n=C->n;
  pi->timeout.tv_sec=puntal->timeout.tv_sec;
  pi->timeout.tv_usec=puntal->timeout.tv_usec;
//  pthread_mutex_unlock(C->lista_lock);
  po=(PARAM_OUT *)ping(pi);
//  pthread_mutex_lock(C->lista_lock);
  puntal->status=po->stato;
  puntal->stat.tmp_ultimo=po->tempo;
  (puntal->stat.tmp_tot)+=po->tempo;
  (puntal->stat.int_tot)++;
  if (puntal->status==EX_ALIVE)
    (puntal->stat.int_ok)++;
  gestione_tmp(puntal);
  puntal=puntal->next;
 }
 pthread_mutex_unlock(C->lista_lock);
 free(pi);
 free(po);
 pthread_exit(retval);
 return NULL;
}
void *ciclo_sock(void *arg)
{
 DATA *D=(DATA *)arg;
 ELEM volatile *puntal;
 void *retval;
 int i, rc, sock;
        char msg[1024];
 rc=recv(D->n, msg, sizeof(msg), 0);
 while (rc>0)
 {
         printf("Ricevuto: %s\n", msg);
  strcpy(msg, "\0");
         printf("pippo1\n");
/* la lock che segue è quella che mi fa saltare tutto alla quinta volta,
praticamente non viene stampato "pippo1.5 */
         pthread_mutex_lock(D->lista_lock);
         printf("pippo1.5\n");
         puntal=D->t_lista;
         printf("pippo2\n");
         while (puntal)
         {
          printf("pippo3\n");
   if ((puntal->stat.int_ok)<((puntal->stat.int_tot)-(puntal->stat.int_ok)))
   {
    if (!(strcmp(msg, "\0"))) strcpy(msg, puntal->ind);
    else strcat(msg, puntal->ind);
    strcat(msg, "\n");
   }
   printf("pippo4\n");
   puntal=puntal->next;
  }
  pthread_mutex_unlock(D->lista_lock);
  if (!(strcmp(msg, "\0"))) strcpy(msg, "Sorry!\n");
  rc=send(D->n, msg, sizeof(msg), 0);
  printf("Fatto send!\n");
  if (rc < 0)
  {
   perror("Send ciclo_sock");
   exit(1);
  }
  printf("Pronto per recv!\n");
  rc=recv(D->n, msg, sizeof(msg), 0);
 }
 pthread_mutex_lock(D->lista_lock);
 D->nostop=0;
 pthread_mutex_unlock(D->lista_lock);
 pthread_exit(retval);
 return NULL;
}
/* primo thread, da qui vengono creati ciclo_ping e ciclo_sock */
void *ciclo(void *arg)
{
// struct timespec delay;
 pthread_t *thread_ping, *thread_sock;
 pthread_mutex_t l_lock;
 DATA *B=(DATA *)arg;
 DATA *Z;
 ELEM volatile *lista, *puntal;
 void *retval;
        int i, j, rc;
        char msg[1024];
 time_t otime;
 thread_ping=(pthread_t *)malloc(sizeof(pthread_t));
 thread_sock=(pthread_t *)malloc(sizeof(pthread_t));
 Z=(DATA *)malloc(sizeof(DATA));
 pthread_mutex_init(&l_lock, NULL);
 rc=recv(B->n, msg, sizeof(msg), 0);
 if (rc < 0)
 {
  perror("Recv ciclo");
  exit(1);
 }
        printf("Ricevuto: %s\n\n", msg);
 pthread_mutex_lock(&l_lock);
 if (estrai_ind(&lista, &otime, msg, FALSE)) printf("Problemi con
preleva_ind()");
 printf("\n\n");
 pthread_mutex_unlock(&l_lock);
 pthread_mutex_lock(&l_lock);
 Z->t_lista=lista;
 Z->n=B->n;
 Z->nostop=1;
 Z->lista_lock=&l_lock;
   pthread_mutex_unlock(&l_lock);
 if (pthread_create(thread_sock, NULL, (void *)ciclo_sock, Z))
 {
  printf("No Thread Create1");
  exit(1);
 }
 i=0;
 pthread_mutex_lock(&l_lock);
 while (Z->nostop)
 {
  B[i].t_lista=lista;
  B[i].n=i;
  B[i].lista_lock=&l_lock;
    pthread_mutex_unlock(&l_lock);
  if (pthread_create(&thread_ping[i], NULL, (void *)ciclo_ping, &B[i]))
  {
   printf("No Thread Create1");
   exit(1);
  }
  sleep(5);
/*  delay.tvsec=5;
  delay.tvnsec=0;
  pthread_delay_np(&delay);*/
  if (file_mod(&otime, msg))
  {
   pthread_mutex_lock(&l_lock);
   if (estrai_ind(&lista, &otime, msg, TRUE)) printf("Problemi con
aggiorna_ind()");
   if (libera_agg(&lista)) printf("Problemi con libera_agg()");
   pthread_mutex_unlock(&l_lock);
  }
  printf("\n\n");
  i++;
  pthread_mutex_lock(&l_lock);
 }
 pthread_mutex_unlock(&l_lock);
 if (pthread_join(*thread_sock, &retval))
 {
  printf("No Thread Join Sock1");
  exit(1);
 }
 for (j=0; j<i; j++)
 {
  if (pthread_join(thread_ping[j], &retval))
  {
   printf("No Thread Join1");
   exit(1);
  }
        }
        printf("\n\n");
 pthread_mutex_lock(&l_lock);
 if (libera_lista(&lista)) printf("Problemi con libera_lista()");
 pthread_mutex_unlock(&l_lock);
 if (pthread_mutex_destroy(&l_lock))
 {
  printf("No Thread Destroy1");
  exit(1);
 }
 pthread_exit(retval);
 return NULL;
}
/* funzione principale per la creazione del primo thread */
int lancia_thread(int sock)
{
 pthread_t *thread;
 void *retval;
 DATA *A;
 thread=(pthread_t *)malloc(sizeof(pthread_t));
 A=(DATA *)malloc(sizeof(DATA));
 A->n=sock;
 if (pthread_create(thread, NULL, (void *)ciclo, (void *)A))
 {
  printf("No Thread Create0");
  exit(1);
 }
 if (pthread_join(*thread, &retval))
 {
  printf("No Thread Join0");
  exit(1);
 }
 return(0);
}
Spero che il codice non sia troppo lungo e non dia problemi a nessuno.
Un'altra domanda: come posso fare dormire un thread e solo quello (la sleep
fa dormire anche tutti i processi collegati) ed il delay non mi funziona.
Grazie.
Mattia.

  pthread_mutex_unlock(D->lista_lock);
Poi mi spiace ma non ho voglia di leggerlo tutto. Se posti una versione
tagliata con piu' spiegazioni se ne puo' riparlare.
Per l'altra domanda: variabili di condizione
man pthread_cond_init
--
  	Giuseppe "Cowo" Corbelli  -->>  Riding on Linux-2.2.16
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
  -<! I Never Wanted To Be What They Told Me To Be
  		Fulfill My Fate Then I'll Be Free >!-
  			Blind Guardian - Mordred's Song

Grazie per la risposta Giuseppe.
Ciao.
Mattia.