[SOLVED] Pthread - correttezza codice

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
mr.simo
Linux 1.x
Linux 1.x
Messaggi: 107
Iscritto il: dom 1 nov 2009, 2:17
Nome Cognome: oxsimo

[SOLVED] Pthread - correttezza codice

Messaggio da mr.simo »

Ciao a tutti, qualche mese fa studiai un po le librerie pthread e sviluppai il seguente esercizio..

Codice: Seleziona tutto

/*multi threads execution simple exemple*/

#include<pthread.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>

pthread_mutex_t condition_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_cond = PTHREAD_COND_INITIALIZER;

void *funz1(void *x)
{
 printf("1) Starting 1st Thread...\n");
 sleep(1);
 /*aquisisce il lock*/
 pthread_mutex_lock(&condition_mutex);
 printf("3) 1st Thread waits 2nd Thread completes his execution...\n");
 sleep(1);
 /*aspetta l'esecuzione di un altro thread*/
 pthread_cond_wait(&condition_cond, &condition_mutex);
 sleep(1);
 pthread_mutex_unlock(&condition_mutex);
 printf("5) 1st Thread completes his execution...\n\n");

 return 0;
}


void *funz2(void *x)
{
 printf("2) Starting 2nd Thread...\n");
 sleep(1);
 /*aquisisce il lock*/
 pthread_mutex_lock(&condition_mutex);
 sleep(1);
 /*riceve il segnale di precendenza per l'esecuzione*/
 pthread_cond_signal(&condition_cond);
 sleep(1);
 pthread_mutex_unlock(&condition_mutex);
 printf("4) 2nd Thread executed...\n");

 return 0;
}

int main()
{
 pthread_t t1, t2;

 printf("\n**Starting execution of threads**\n\n");

 if(pthread_create(&t1, NULL , funz1, NULL) != 0)
 { 
  printf("Error generating threads\n");
  return 1;
 }

 if(pthread_create(&t2, NULL , funz2, NULL) != 0)
 { 
  printf("Error generating threads\n");
  return 1;
 }

 pthread_join(t1, NULL);
 pthread_join(t2, NULL);

 return 0;
}
Premetto che non ho passato molto tempo sull'argomento per via di altri impegni, pero oggi ho potuto verificare ciò:
Su una ubuntu il risultato è quello "voluto"; ossia 1, 2, 3, 4, 5 in ordine..
Sulla mia slack 12.2 invece ci sono problemi: dopo il 4 si blocca, in uno sleep senza limite di tempo..

Codice: Seleziona tutto

**Starting execution of threads**

1) Starting 1st Thread...
2) Starting 2nd Thread...
3) 1st Thread waits 2nd Thread completes his execution...
4) 2nd Thread executed...
^C
simo@localhost:
Se tolgo gli sleep dal codice il risultato è il seguente:

Codice: Seleziona tutto

**Starting execution of threads**

1) Starting 1st Thread...
3) 1st Thread waits 2nd Thread completes his execution...
2) Starting 2nd Thread...
5) 1st Thread completes his execution...

4) 2nd Thread executed...
Da cosa può essere dato il problema? Uso il kernel di default, non ho toccato la selezione nel file lilo.conf pero non capisco da cosa può nascere il problema. Qualcuno mi sa aiutare o dare qualche indicazione?
Grazie a tutti!
Ultima modifica di mr.simo il gio 15 apr 2010, 15:41, modificato 1 volta in totale.

Avatar utente
Ansa89
Iper Master
Iper Master
Messaggi: 2703
Iscritto il: mer 29 ago 2007, 17:57
Nome Cognome: Stefano Ansaloni
Slackware: 14.2 64bit
Kernel: 4.9.61
Desktop: XFCE 4.12
Località: Modena

Re: Pthread - correttezza codice

Messaggio da Ansa89 »

Non ho perso molto tempo a guardare il codice (è mattina presto), ma l'ordine differente di esecuzione è probabilmente dovuto al differente algoritmo di cpu-scheduling che viene usato da ubuntu e slack.

Il perché si blocchi se nel primo caso non lo so :? .

Avatar utente
Luke88
Linux 3.x
Linux 3.x
Messaggi: 624
Iscritto il: mer 7 set 2005, 0:00
Slackware: 13.0
Kernel: 2.6.30-zen4
Desktop: xfce4
Località: Udine

Re: Pthread - correttezza codice

Messaggio da Luke88 »

Succede:
-funz1:printf (1)
-funz2:printf (2), mutex_lock, signal, mutex_unlock
-funz1:mutex_lock, printf (3), condition_wait
-funz2:printf(4)

e ovviamente, deadlock, in quanto funz1 aspetta il segnale che non arriverà mai.

datti una letta al kernighan comunque, nelle funzioni void non va messo il return e le tue funzioni prendono un argomento che non gli viene passato...
se ti va poi datti una letta allo stile di programmazione linux ( /usr/src/linux/Documentation/CodingStyle ), il migliore (imho) per programmare in C.

nel secondo caso invece:
-funz1: printf(1), mutex_lock, printf(3), condition_wait
-funz2: printf(2), mutex_lock, signal, mutex_unlock
-funz1: mutex_unlock, printf(5)
-funz2: printf(4)

l'utilità dei thread è proprio quella: le istruzioni possono venire eseguite in parallelo (più o meno), ma in qualsiasi ordine.
Meeting efficency = Average_Intelligence/( Number_Of_People^2 )

Avatar utente
mr.simo
Linux 1.x
Linux 1.x
Messaggi: 107
Iscritto il: dom 1 nov 2009, 2:17
Nome Cognome: oxsimo

Re: Pthread - correttezza codice

Messaggio da mr.simo »

datti una letta al kernighan comunque, nelle funzioni void non va messo il return e le tue funzioni prendono un argomento che non gli viene passato...
se ti va poi datti una letta allo stile di programmazione linux ( /usr/src/linux/Documentation/CodingStyle ), il migliore (imho) per programmare in C.
Grazie per la tua risposta.. :lol: Ho letto kernigham e libri molto piu impegnativi, pero essendo umani gli errori li possiamo fare tutti, anche se in effetti i return ai void era meglio correggerli, da dire che se non me li segnalava :-k . Distrazione mia e altri fattori... Grazie per ricordarmelo :thumbright: :D

Fatto stà che ho risolto.. L'errore come mi ha fatto notare Luke88 era alla riga nº 25 dove appunto pthread_mutex_unlock(&condition_mutex) causava un deadlock.. Ora il codice funziona come voluto. Grazie per avermi fatto notare questo dettaglio. comunque tornerò personalmente sull'argomento.. :D
Dunque il codice rimane il seguente:

Codice: Seleziona tutto

/*multi threads execution simple exemple*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

pthread_mutex_t condition_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_cond = PTHREAD_COND_INITIALIZER;

void *funz1(void *x)
{
  printf("1) Starting 1st Thread...\n");
  /*aquisisce il lock*/
  pthread_mutex_lock(&condition_mutex);
  sleep(1);
  printf("3) 1st Thread waits 2nd Thread completes his execution...\n");
  sleep(1);
  /*aspetta l'esecuzione di un altro thread*/
  pthread_cond_wait(&condition_cond, &condition_mutex);
  sleep(1);
  /*pthread_mutex_unlock(&condition_mutex); ERRORE*/;
  printf("5) 1st Thread completes his execution...\n\n");
}


void *funz2(void *x)
{
  printf("2) Starting 2nd Thread...\n");
  /*aquisisce il lock*/
  pthread_mutex_lock(&condition_mutex);
  sleep(1);
  /*riceve il segnale di precendenza per l'esecuzione*/
  pthread_cond_signal(&condition_cond);
  sleep(1);
  pthread_mutex_unlock(&condition_mutex);
  printf("4) 2nd Thread executed...\n");
}

int main()
{
  pthread_t t1, t2;
  printf("\n**Starting execution of threads**\n\n");

  if(pthread_create(&t1, NULL , funz1, NULL) != 0)
  { 
    printf("Error generating threads\n");
    return 1;
  }

  if(pthread_create(&t2, NULL , funz2, NULL) != 0)
  { 
    printf("Error generating threads\n");
    return 1;
  }

  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  return 0;
}
Ciao grazie mille!!!

Avatar utente
Luke88
Linux 3.x
Linux 3.x
Messaggi: 624
Iscritto il: mer 7 set 2005, 0:00
Slackware: 13.0
Kernel: 2.6.30-zen4
Desktop: xfce4
Località: Udine

Re: [SOLVED] Pthread - correttezza codice

Messaggio da Luke88 »

uh... no.

per cominciare, le tue due funzioni non ritornano void, ma puntatori a void, quindi stai ancora sbagliando la dichiarazione.
poi le tue funzioni prendono ancora un argomento, anche se non glielo passi.

metti quelle funzioni a void, togli gli argomenti e fai partire i thread con casting a puntatore a void dell'indirizzo della funzione.

comunque può ancora andare in deadlock.
esempio:

-funz2:printf(2), mutex_lock, signal, mutex_unlock, printf(4)
-funz1:printf(1), mutex_lock, printf(3), condition_wait

deadlock, sta in attesa del segnale che non arriverà mai.

inoltre, direttamente dal man di pthread_cond_wait:
man ha scritto: These functions atomically release mutex and cause the calling thread to block on the condition variable cond;

Upon successful return, the mutex shall have been locked and shall be owned by the calling thread.
ergo la cond_wait prima rilascia la mutex, sta in attesa del segnale, e appena riceve il segnale riblocca la mutex, e esce.

funz1 non rilascia la mutex. termina (a volte), ma la mutex è sempre bloccata.
Meeting efficency = Average_Intelligence/( Number_Of_People^2 )

Avatar utente
mr.simo
Linux 1.x
Linux 1.x
Messaggi: 107
Iscritto il: dom 1 nov 2009, 2:17
Nome Cognome: oxsimo

Re: [SOLVED] Pthread - correttezza codice

Messaggio da mr.simo »

per cominciare, le tue due funzioni non ritornano void, ma puntatori a void, quindi stai ancora sbagliando la dichiarazione.
poi le tue funzioni prendono ancora un argomento, anche se non glielo passi.
Si per gli argomenti hai ragione li creai inutilmente.. Altra stupidaggine.
pthread_create prende comunque come 3º argomento un puntatore a void.. Per questo feci cosi.. App arr a casa seguo il tuo consiglio. :thumbright:

EDIT: ho tolto gli argomenti inutili etc, comunque il deadlock comunque non si verifica.. Dovrebbe andare bene cosi credo.. :-k

Rispondi