pthread linux

#2548102
Lesenswert?

Hi,
Ich bin grad ein wenig am verzweifeln an threadprogrammierung für eine 
Fritzbox(7170)-Anwendung.

Ich habe folgenden Code:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <inttypes.h>
5
#include <stdbool.h>
6

7
#include <time.h>
8
#include <pthread.h>
9

10

11
#ifdef _WIN32
12
#  include <windows.h>
13
#  define sleepMs(x) do{Sleep(x);}while(0)
14
#else
15
#  include <unistd.h>
16
static void sleepMs(uint32_t ms)
17
{
18
  struct timespec sleepTime;
19
  struct timespec remainingSleepTime;
20
  sleepTime.tv_sec  = ms/1000;
21
  sleepTime.tv_nsec = (ms%1000)*1000000;
22
  nanosleep(&sleepTime,&remainingSleepTime);
23
}
24
#endif
25

26

27
void* receiveThread(void* arg)
28
{
29
  while(23){
30
    printf("iam the thread loop\n");
31
    sleepMs(2000);
32
  }
33
}
34

35
int main(void)
36
{
37
  pthread_t thread = {0};
38
  int rc;
39
  printf("enter main\n");
40

41
  rc = pthread_create( &thread, NULL, &receiveThread, NULL);
42
  if(rc){
43
   perror("could not create THread\n");
44
  }
45
  printf("started thread\n");
46

47
  while(1)
48
  {
49
    printf("iam the main loop\n");
50
    sleepMs(1000);
51
  }
52
  return EXIT_SUCCESS;
53
}


unter windows läuft er wie erwaretet.
ich benutze visual studio 2008 express mit einer windows pthread 
bibliothek (die leider die sleep funktionen nicht kennt, deswegen die 
unterscheidung)

auf der Fritzbox läuft das ganze dann so, dass ich nur die ausschriften 
der main-loop bekomme.
1
root@fritz:/var/media/ftp/uStor11# ./helloworld
2
enter main
3
started thread
4
iam the main loop
5
iam the main loop
6
iam the main loop
7
iam the main loop

kan nmir hier jemand weiterhelfen?
Ich hau mich jetzt erst mal aufs Ohr.

MfG
Vlad
Gast #2548129
Lesenswert?

Könnte ein Problem im Threading des Linuxkernels auf deiner Fritzbox 
sein, auf 3 verschiedenen Linuxsystemen (Desktop, Atom, NAS) lies sich 
dein Code wie zu erwarten Ausführen.

Ansonsten wie hast du kompiliert?

gcc -lpthreads source.c -o binary
oder
gcc -D_REENTRANT -lpthreads source.c -o binary
oder
gcc -pthreads source.c -o binary
#2548212
Lesenswert?

Tim T. schrieb:
> Könnte ein Problem im Threading des Linuxkernels auf deiner Fritzbox
> sein, auf 3 verschiedenen Linuxsystemen (Desktop, Atom, NAS) lies sich
> dein Code wie zu erwarten Ausführen.
oh mann, wieso habe ich das befürchtet.
Die anderen Tools laufen doch auch.

Tim T. schrieb:
> Ansonsten wie hast du kompiliert?
>
> gcc -lpthreads source.c -o binary
> oder
> gcc -D_REENTRANT -lpthreads source.c -o binary
> oder
> gcc -pthreads source.c -o binary

was wäre denn richtig? Was sind die Unterschiede?

hab gerade das Makefile nicht zur hand, aber ich glaube so:
gcc -lpthreads source.c -o binary
die anderen beiden auf gar keinen Fall.
Gast #2548266
Lesenswert?

Vlad Tepesch schrieb:
> Tim T. schrieb:
>> Könnte ein Problem im Threading des Linuxkernels auf deiner Fritzbox
>> sein, auf 3 verschiedenen Linuxsystemen (Desktop, Atom, NAS) lies sich
>> dein Code wie zu erwarten Ausführen.
> oh mann, wieso habe ich das befürchtet.
> Die anderen Tools laufen doch auch.
>
> Tim T. schrieb:
>> Ansonsten wie hast du kompiliert?
>>
>> gcc -lpthreads source.c -o binary
>> oder
>> gcc -D_REENTRANT -lpthreads source.c -o binary
>> oder
>> gcc -pthreads source.c -o binary
>
> was wäre denn richtig? Was sind die Unterschiede?
>
> hab gerade das Makefile nicht zur hand, aber ich glaube so:
> gcc -lpthreads source.c -o binary
> die anderen beiden auf gar keinen Fall.

Variante 1 linkt einfach nur pthreads dazu.
Variante 2 ist wie Variante 1 nur das zusätzlich die Threadsicheren 
Standardbibliotheken benutzt werden.
Variante 3 sollte die Kurzform von Variante 2 sein.

Also richtig wäre Variante 3 bzw. 2.

Und das mit dem Funktionspointer ist egal.
Gast #2548304
Lesenswert?

Vlad Tepesch schrieb:
> das sollte egal sein, oder?

Stimmt ... ich konnte es gar nicht glauben. Mit dem & würde man ja 
eigentlich eine Pointer auf einen Funktionspointer übergeben - was in 
dem Fall ja erstmal falsch wäre. Müsste dann ja aber auch vom Compiler 
angemeckert werden.
Es geht tatsächlich beides - warum auch immer... wenn ich einer Variable 
einen Funktionspointer zuweise schreibe ich ja auch

var_func = function;

und nicht

var_func = &function;

(Am Ende geht das auch? Hab ich jetzt nicht überprüft.)
#2548496
Lesenswert?

Tim T. schrieb:
> Variante 2 ist wie Variante 1 nur das zusätzlich die Threadsicheren
> Standardbibliotheken benutzt werden.
> Variante 3 sollte die Kurzform von Variante 2 sein.
>
> Also richtig wäre Variante 3 bzw. 2.
ah - ok, das werde ich heut abend mal ausprobieren.
dann wundert es mich aber, dass das ganze nicht abstürzt, oder müll 
ausgegeben wird, wenn die stdlib (in dem Fall wird ja nur das printf 
benutzt) nicht threadsafe ist.


Holger schrieb:
> (Am Ende geht das auch? Hab ich jetzt nicht überprüft.)

na klar geht das auch.
Ein Argument zu übergeben ist doch syntaktisch eine Zuweisung an den 
Parameter.

Ich benutze lieber das &, da das explizit aussagt, dass hier die Adresse 
von etwas zurückgegeben wird.
#2548619
Lesenswert?

Vlad Tepesch schrieb:
> dann wundert es mich aber, dass das ganze nicht abstürzt, oder müll
> ausgegeben wird, wenn die stdlib (in dem Fall wird ja nur das printf
> benutzt) nicht threadsafe ist.

Das passiert ja nur, wenn der Taskwechsel erfolgt, während der eine 
Thread gerade in der printf ist und nach dem Taskwechsel der andere 
Thread auch in der printf ist oder hineingeht, und ein (globaler) 
Zustand der printf verändert wird. Es ist also relativ unwahrscheinlich, 
daß das passiert. Deshalb bleiben solche Fehler auch lange unentdeckt 
und sind schwer zu finden.
Moderator Persönliche Seite #2548863
Lesenswert?

Vlad Tepesch schrieb:
> mensch Jörg, warum hast du das jetzt schon wieder verschoben?

Mensch Vlad, warum nimmst du an, dass alles, was dir an der Moderation
nicht passt, durch mich erfolgt ist?

> Auf PCs scheint es kein Problem zu geben.

Dann hat entweder dein Kernel auf dem Gerät eine Macke, oder du bist
im Compilieren zwischen beiden halt nicht konsistent.  Wenn Threads
angeboten werden, sollten sie unabhängig von der Hardwareplattform
mit gleichem API funktionieren.

Die Linux-Experten (die du für die Beantwortung dieser Frage brauchst)
wirst du aber ohnehin eher hier in diesem Forum finden, auch wenn deine
Zielplattform ein MIPS ist.
Gast #2548918
Lesenswert?

Jörg Wunsch schrieb:
> Tim T. schrieb:
>
>> Ansonsten wie hast du kompiliert?
>>
>> gcc -lpthreads source.c -o binary
>> oder
>> gcc -D_REENTRANT -lpthreads source.c -o binary
>
> -l-Optionen vor den eigentlichen Objekten (bzw. Quelldateien) sind
> witzlos.  -l-Optionen gehören immer nach hinten.

Das steht zwar immernoch in gewissen O'Reilly Büchern, hat aber 
ansonsten nichts zu sagen, nur die Reihenfolge der Libs untereinander 
ist von Bedeutung.
Moderator Persönliche Seite #2548946
Lesenswert?

Tim T. schrieb:
> Das steht zwar immernoch in gewissen O'Reilly Büchern, hat aber
> ansonsten nichts zu sagen, nur die Reihenfolge der Libs untereinander
> ist von Bedeutung.

Wenn du nicht weißt, warum das in "gewissen O'Reilly Büchern" steht,
dann verbreite bitte wenigstens kein Halbwissen.

Es spielt nämlich nur so lange keine Rolle, wie sämtliche via -l
referenzierten Bibliotheken dynamisch gelinkt werden(*).  Sowie sich
dahinter eine statische Bibliothek versteckt, spielt die Reihenfolge
sehr wohl wieder eine Rolle.

(*) Selbst da wäre ich mir nicht völlig sicher, ob nicht-GNU-Linker
(zum Beispiel auf Solaris) da genauso reagieren.

Auch auf einem System, was im Wesentlichen mit dynamischen Bibliotheken
arbeitet, kann es Gründe geben, warum bestimmte Bibliotheken nicht
als dynamische Bibliothek vorliegen.  Ob dem so ist, kann man der
Linker-Kommandozeile aber nicht ansehen.

Spätestens, wenn man aus irgendeinem Grunde mal komplett statisch
linkt (via -static), wäre ohnehin Schluss mit lustich.
Moderator Persönliche Seite #2549023
Lesenswert?

Tim T. schrieb:
> dürfte daran liegen das es so im Manual steht

Weil der Linker die Bibliotheken nur zur Auflösung von an dieser
Stelle noch vorhandnene "global undefined"-Referenzen benutzt.

Wenn man die Bibliotheken vor den Objekten linkt, ist noch gar nichts
(außer "main", aus dem crt0.o) "global undefined", folglich wird dann
nichts gelinkt.

Dass es bei dynamischen Bibliotheken — zumindest beim GNU-Linker —
anders läuft liegt daran, dass er diese beim Nennen auf der Kommando-
zeile tatsächlich in die Liste der zur Laufzeit hinzuzulinkenden
shared libs aufnimmt und damit deren Symboltabellen komplett
übernimmt.  Aber wie geschrieben: ich würde mich nicht drauf
verlassen, dass das jeder Linker so tut.

> was aber hierzu auch keine Begründung liefert.

Selbstverständlich liefert es die:

     The linker will search an archive only once, at the location
     where it is specified on the command line.  If the archive
     defines a symbol which was undefined in some object which
     appeared before the archive on the command line, the linker will
     include the appropriate file(s) from the archive.  However, an
     undefined symbol in an object appearing later on the command line
     will not cause the linker to search the archive again.
Gast #2549257
Lesenswert?

Jörg Wunsch schrieb:
> Selbstverständlich liefert es die:
>
>      The linker will search an archive only once, at the location
>      where it is specified on the command line.  If the archive
>      defines a symbol which was undefined in some object which
>      appeared before the archive on the command line, the linker will
>      include the appropriate file(s) from the archive.  However, an
>      undefined symbol in an object appearing later on the command line
>      will not cause the linker to search the archive again.

Hmm, diesen Passus habe ich im aktuellen Manual nicht gefunden, 
eventuell einen Tip wo ich suchen muss?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren