Newsgroup: it.comp.os.linux.iniziare
Titolo: [1/2 OT] Gcc e pthread

Salve a tutto l'ng.
Probabilmente il msg č abbastanza OT oltre ad essere decisamente lungo, ma
vista l'urgenza e non avendo trovato alcun rimedio su google...
Innanzitutto ho una debian upgradata a sid e *devo* imparare ad usare i
thread sotto linux: quelli di voi che usano una debian (qualsiasi essa sia)
possono compilare il file in coda al msg e postare gli eventuali errori di
gcc?
Nel caso non si riscontri alcunche e la compilazione vada a buon fine
possono indicare, potete indicare la versione di gcc, libc6 e di binutils
istallate?
Il problema che riscontro (nel mio caso usando le funzioni di pthread.h) č
che nonostante una corretta sintassi e semantica delle funzioni (per lo meno
cosi mi pare), vengono generati questi errori:
io@D998:~/projects/prova_C$ gcc-2.95 -x c u2. -o u2
/tmp/ccDteQfx.o: In function `main':
/tmp/ccDteQfx.o(.text+0x10f): undefined reference to `pthread_create'
/tmp/ccDteQfx.o(.text+0x15f): undefined reference to `pthread_join'
collect2: ld returned 1 exit status
L'errore si ripresenta anche con altri file (sia presi dalla rete, che
scritti da me) che sfruttano i thread.
Ho provato sia con gcc-2.95 (originale della woody) che con gcc-3.3-pre9.
Ho provato ad usare le binutils (che contengono ld) della woody, e di sid.
Ho provato le libc6 2.3.1-10 e 2.3.1-17.
In nessun caso la compilazione termina correttamente.
Ho notato che altre funzioni di pthread.h non generano alcun errore con gcc
(ad esempio pthread_exit).
Dove sbaglio?
Devo reinstallare la woody?
Mi potete indirizzare verso un documento che spieghi correttamente i vari
errori di gcc?
Grazie mille!
                      Jorge
**********************************************
/* Copyright 2002, Shugyo Design Technologies. */
/*
 * Demonstrates pthread_create and pthread_join.
 *
 * Printing of pthread_t objects is not portable.  This example
 * assumes they are int.
 */
#include <pthread.h>
#include <stdio.h>
typedef struct
{
    const long loops;   /* Number of loops for worker to execute.  */
    long answer;        /* The hash value resulting from the work. */
    pthread_t id;       /* The threads id object.                  */
}
thread_data;
/*
 * Do some work on thread_data, return a pointer to the result.  This
 * thread does not yield the cpu while working.  In main() below, three
 * copies of this are run in parallel as threads.
 */
static void * worker (void *p)
{
    thread_data *data = p;
    volatile long l;
    printf ("(%d) starting coundown from %ld\r\n", data->id, data->loops);
    l = data->loops;
    data->answer = 0;
    while (l--)
    {
        /* Some useless hash calculation: */
        data->answer ^= (l & 1);
        data->answer = (data->answer << 1) + (data->answer >> 31);
    }
    printf ("(%d) done\r\n", data->id);
    /* pthread_join() will get this pointer */
    return & data->answer;
}
int main (void)
{
    thread_data threads[3] =
    {
        {100000L},
        {1000000L},
        {2000000L}
    };
    int i;
    void *result;
    long out;
    /* Start the worker bees: */
    for (i = 0; i < 3; i++)
    {
        pthread_create (& threads[i].id, NULL, worker, &threads[i]);
    }
    printf ("join.\r\n");
    /* Wait for the workers: */
    for (i = 0; i < 3; i++)
    {
        if (0 == pthread_join (threads[i].id, & result))
        {
            out = *(long *)result;
            /* Show the results of the work: */
            printf ("Joined with %d, answer is %lu\r\n",
                    threads[i].id,
                    out);
        }
        else
        {
            printf ("Join error!\r\n");
        }
    }
    printf ("Done...\r\n");
    return 0;
}
--
WinPT Fingerprint  with GnuPG
17E9 A75D AAED 6CC5 9A41 8D33 2986 EA20 6AA5 9B59

 Dove sbaglio?
Non linki la libreria di pthread:
aggiungi -lpthread  ai flags di gcc.
-- 
Ikitt	*** mailserver: 
freemail.it
"Linux non pare reggere il confronto con windows: oltre a consumare molte 
piu` risorse di sistema, e` rigido nella pretesa di avere un tot numero di
cartelle nella radice" (da 
http://mondoweb.culturanuova.net/mondo_pc.php
)

 aggiungi -lpthread  ai flags di gcc.
E' vero!!!
Passando quella opzione la compilazione va a buon fine: come mai c'e bisogno
di "avvertire" esplicitamente il compilatore, mentre non basta includere
pthread.h?
Eppure sono (quasi) sicuro che nel man di gcc -lpthread non sia specificata
per nulla...
Boh... vabbe per il momento mi basta aver risolto...
Comunque hai mica qualche link sottomano sulle varie opzioni di gcc?
Ciao e grazie,
                                    Jorge


 Comunque hai mica qualche link sottomano sulle varie opzioni di gcc?
Nulla di particolare che non sia man gcc :(


 Nulla di particolare che non sia man gcc :(
Ho scaricato il manuale ufficiale da 
gnu.org
, ma nonostante non lo abbia
ancora aperto, ho come l'impressione che non si allontani molto dai file di
doc presenti su debian.org... spero vivamente di sbagliarmi!
Ciao,


 doc presenti su debian.org... spero vivamente di sbagliarmi!
Quello di gcc 2.95.x era un po` criptico, mentre quello di 3.x mi pare assai
migliore...


 pare assai migliore...
Ci credi che non ho avuto ancora tempo di dargli un'occhiata?
Ma perche le giornate non sono di 50 ore? Uff...
Saluti,


 Ma perche le giornate non sono di 50 ore? Uff...
A chi lo dici...


 Eh, male non faresti!!! :) Sono tutt'orecchi!
Proviamoci.
Non credo di riuscire a descrivere efficaciemente come funzionano le cose
sul serio, ma spero di riuscire a non allontanarmi troppo dal vero...
Sopratutto, i concetti dovrebbero essere quelli.
Allora, scomponiamo per comodita` la fase di compilazione in un numero
di sottofasi (la cui utilita`, spero, sara` piu` chiara in seguito)
1) traduzione da codice alto livello ad assembler
2) assemblaggio (traduzione in codice macchina)
3) collegamento (linking, statico o dinamico)
Supponiamo per comodita` di lavorare a livello codice assembler
(gcc -S).
Quando si fa un 
#include "pippo.h"
il compilatore (meglio, il preprocessore) barbaramente prende /dove/sta/pippo.h
e lo copia all'interno del file che lo include, o almeno questo accade
nel caso di gcc.
Il succo, pero`, e` che gli identificatori definiti in pippo.h (nomi di 
variabili e di funzioni...) adesso sono noti al file includente (pippo.c, 
nel proseguio).
Finito di includere quel che serve, si passa ad analizzare pippo.c.
Nell'ipotesi che l'assemblatore (as) lavori in due passate, si ha:
prima passata: as si costruisce una tabella in cui memorizza il nome di ogni 
identificatore ed il suo indirizzo.
seconda passata: as sostituisce l'indirizzo precedentemente trovato al posto
degli identificatori, ottenendo cosi` il codice macchina finale.
Ma che succede quando as NON puo` determinare l'indirizzo di 
un'identificatore?
Se ci si pensa, questo e` il caso nostro/tuo: in pthread.h sono DICHIARATE,
non sempre DEFINITE una serie di variabili e funzioni...
Ovvero, il compilatore sa che esistono tali simboli... Ma dove stanno?
Beh, in questi casi as non inventa... usa un'indirizzo fittizzio per
gli indirizzi sconosciuti, e passa la palla al linker, ld.
Ed eccoci alla fase finale... Che fa ld? Prende i file oggetto (codice 
macchina), li collega, aggiunge quel che serve per rendere il programma 
eseguibile, e termina con successo :)
*Come* li collega? Analizza i file oggetto fornitigli in cerca dell'indirizzo
fasullo che mette as. Se lo trova, si guarda intorno e prova a risolverlo.
Ha sostanzialmente due strade per farlo: cercare simboli esportati da altri
file oggetto (extern char* nome, funzioni globali...), oppure cercare nelle
librerie dove gli e` stato detto di guardare (flag -l di gcc!)...
Se non trova nulla... Alza bandiera bianca, e torna con errore.
Quindi, cos'era successo nel tuo caso?
Includendo "pthread.h" avevi dei simboli non risolti (pthread_exit ed altri,
se ben ricordo). compilatore (c->assembler) e assemblatore 
(assembler->oggetto) ci sono passati sopra scaricando la responsabilita` al 
linker, il quale ha cercato di risolvere i simboli nei sorgenti che te avevi 
scritto, i quali, giustamente, non soddisfacevano la richiesta. E allora ha 
abortito.
Indicandogli -lpthread, lo abbiamo fatto contento: li` i simboli dichiarati
sono anche definiti, e quindi possono essere usati :)
Spero di non aver confuso troppo le acque :)
Per gli sviluppatori all'ascolto: ho abbozzato parecchio (ma certe cose non
le conosco perfettamente neanche io), per motivi di peso e dimensioni del
messaggio... Al solito, correzioni di sfondoni e macroscopiche imprecisioni
sono ben volute e incoraggiate.


 imprecisioni sono ben volute e incoraggiate.
Beh se ci fossero, sarebbero bene accetti alla conversazione... :)
A questo punto ho solo il *piccolo* terrore che, nonostante la app compili
correttamente sul mio notebook (quando sara pronta), faccia poi cilecca sul
comp del professore....
Forse usare gcc-3.3 non è la scelta migliore...
Sara bene che mi informi su che piattaforma verra compilata l'app...
Beh che dire, Miiiille^Miiiille grazie, per la dettagliata spiegazione.
Ora attendo speranzoso qualche altro lumicino sulle domande di cui sopra...
:)


 Ora attendo speranzoso qualche altro lumicino sulle domande di cui sopra...
Di nulla, se e` servita :)
-- 
ikitt	*** mailserver: 
freemail.it
