Repository 32bit  Forum
Repository 64bit  Wiki

[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.

[SOLVED] Pthread - correttezza codice

Messaggioda mr.simo » mer apr 14, 2010 21:13

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 apr 15, 2010 14:41, modificato 1 volta in totale.
Avatar utente
mr.simo
Linux 2.0
Linux 2.0
 
Messaggi: 105
Iscritto il: dom nov 01, 2009 2:17
Nome Cognome: oxsimo

Re: Pthread - correttezza codice

Messaggioda Ansa89 » gio apr 15, 2010 7:28

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
Ansa89
Iper Master
Iper Master
 
Messaggi: 2623
Iscritto il: mer ago 29, 2007 16:57
Località: Modena
Nome Cognome: Stefano Ansaloni
Slackware: 13.1
Kernel: 3.16.1-ck1
Desktop: XFCE 4.6.1

Re: Pthread - correttezza codice

Messaggioda Luke88 » gio apr 15, 2010 10:27

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
Luke88
Linux 2.6
Linux 2.6
 
Messaggi: 624
Iscritto il: mar set 06, 2005 23:00
Località: Udine
Slackware: 13.0
Kernel: 2.6.30-zen4
Desktop: xfce4

Re: Pthread - correttezza codice

Messaggioda mr.simo » gio apr 15, 2010 14:40

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
mr.simo
Linux 2.0
Linux 2.0
 
Messaggi: 105
Iscritto il: dom nov 01, 2009 2:17
Nome Cognome: oxsimo

Re: [SOLVED] Pthread - correttezza codice

Messaggioda Luke88 » gio apr 15, 2010 16:47

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
Luke88
Linux 2.6
Linux 2.6
 
Messaggi: 624
Iscritto il: mar set 06, 2005 23:00
Località: Udine
Slackware: 13.0
Kernel: 2.6.30-zen4
Desktop: xfce4

Re: [SOLVED] Pthread - correttezza codice

Messaggioda mr.simo » gio apr 15, 2010 18:03

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
Avatar utente
mr.simo
Linux 2.0
Linux 2.0
 
Messaggi: 105
Iscritto il: dom nov 01, 2009 2:17
Nome Cognome: oxsimo


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite