• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Header Datei runterladen

blubblub

Newbie
hi,

ich arbeite das erste mal mit linux (openSuse 11.2), und hab ein kleines programm geschrieben, für welches ich die <pthread.h> headerdatei brauche.
mein programm sieht so aus:


Code:
#include <stdio.h>
#include <stdlib.h>           
#include <pthread.h>

#define MAX 10000


pthread_t trd1;										
pthread_t trd2;											

void* mein_thread(void* arg)
{
	

	if( pthread_equal(pthread_self(), trd1) != 0 )				 		
	{
		for(long i=0; i < MAX/2; i++)							
		  printf("Meine Thread ID: %d,   derzeitiger Zählerstand: %5ld", trd1, i); 
	}
	else if( pthread_equal(pthread_self(), trd2) != 0 )
	{
		for(long j=0; j < MAX/2; j++)
		  printf("Meine Thread ID: %d,   derzeitiger Zählerstand: %5ld", trd2, j);
	}
	else
	{
		 fprintf(stderr, "Error");	
		 exit(1);
	}
	
	
	return NULL;
}

int main()
{
 	pthread_create(&trd1, NULL, &mein_thread, NULL);					
	pthread_create(&trd2, NULL, &mein_thread, NULL);

	pthread_exit(NULL);								

	return 0;
}



folgender fehler wird ausgeben, wenn ich über die konsole make eintippe, daraus schließe ich dass die oben genannte headerdatei fehlt.
nun hab ich keine ahnung von linux und wäre dankbar wenn mir jemand eine schritt für schritt anleitung geben könnte, wie ich diese datei
heruntergeladen bekomme.

Code:
gcc -c A3Nr2AKTUELL.c
gcc -o prog A3Nr2AKTUELL.o
A3Nr2AKTUELL.o: In function `main':
A3Nr2AKTUELL.c:(.text+0x109): undefined reference to `pthread_create'
A3Nr2AKTUELL.c:(.text+0x122): undefined reference to `pthread_create'
collect2: ld returned 1 exit status
make: *** [prog] Fehler 1
 

Tooltime

Advanced Hacker
blubblub schrieb:
folgender fehler wird ausgeben, wenn ich über die konsole make eintippe, daraus schließe ich dass die oben genannte headerdatei fehlt.
Weder Präprozessor noch Compiler haben einen Fehler ausgegeben, wieso sollte da der Header fehlen?

Ich würde mal spontan vermuten das der Linker die Bibliothek für pthread_xxx() nicht findet. Ein man pthread_create sagt:
  • Compile and link with -pthread.
 
OP
B

blubblub

Newbie
hab jetzt beide varianten ausprobiert. aber es funktioniert immer noch nicht.
bei gcc A3Nr2AKTUELL.c -lpthread -std=c99 , der erste buchstabe bei "-lpthred" ist doch ein "L" und kein "I" oder?

Code:
pj@linux-7z48:~/bin/KMS2> ls
A3Nr2AKTUELL.c  A3Nr2AKTUELL.o  a.out  BASH  BASH~  makefile  makefile~
pj@linux-7z48:~/bin/KMS2> gcc A3Nr2AKTUELL.c -lpthread -std=c99
pj@linux-7z48:~/bin/KMS2> make
gcc -o prog A3Nr2AKTUELL.o
A3Nr2AKTUELL.o: In function `main':
A3Nr2AKTUELL.c:(.text+0x109): undefined reference to `pthread_create'
A3Nr2AKTUELL.c:(.text+0x122): undefined reference to `pthread_create'
collect2: ld returned 1 exit status
make: *** [prog] Fehler 1
pj@linux-7z48:~/bin/KMS2>

Code:
pj@linux-7z48:~/bin/KMS2> ls
A3Nr2AKTUELL.c  A3Nr2AKTUELL.o  a.out  BASH  BASH~  makefile  makefile~
pj@linux-7z48:~/bin/KMS2> Compile and link with -pthread
If 'Compile' is not a typo you can use command-not-found to lookup the package that contains it, like this:
    cnf Compile
pj@linux-7z48:~/bin/KMS2> cnd Compile
If 'cnd' is not a typo you can use command-not-found to lookup the package that contains it, like this:
    cnf cnd
pj@linux-7z48:~/bin/KMS2>
 

Tooltime

Advanced Hacker
blubblub schrieb:
Code:
pj@linux-7z48:~/bin/KMS2> ls
A3Nr2AKTUELL.c  A3Nr2AKTUELL.o  a.out  BASH  BASH~  makefile  makefile~
pj@linux-7z48:~/bin/KMS2> Compile and link with -pthread
??? Du hast doch nicht einfach in der Konsole Compile and link with -pthread eingegeben? Mein Englisch ist wirklich nicht das beste, aber das sollte doch wohl jeder übersetzen können.

Habe deinen Code bei mir mal als test.c gespeichert und dann sieht das so aus:
Code:
tooltime@athlon:~/test/build/Forum> ls
test.c
tooltime@athlon:~/test/build/Forum> gcc -c -std=c99 -pthread test.c
tooltime@athlon:~/test/build/Forum> gcc -pthread -o test test.o
tooltime@athlon:~/test/build/Forum> ls
test  test.c  test.o
tooltime@athlon:~/test/build/Forum>
Wie man sieht nix Problem. Prinzipiell hat der Kollege abgdf recht, denke aber das mit dem Flag (-pthread) das komplette stdio auf threadsicher umgestellt wird.
 
OP
B

blubblub

Newbie
also ich hab jetzt nochmal nen versuch gestartet:
wenn ich gcc -c std=c99 -pthread A3Nr2AKTUELL.c eingebe und mit enter abschließe,
dann macht er nichts.
hab danach nochmal make eingegeben um zu gucken, ob nicht vielleicht doch irgendwas gemacht wurde,
aber es kommt wieder dieselbe meldung

Code:
pj@linux-7z48:~/bin/KMS2> ls
A3Nr2AKTUELL  A3Nr2AKTUELL.c  A3Nr2AKTUELL.o  a.out  BASH  BASH~  makefile  makefile~
pj@linux-7z48:~/bin/KMS2> gcc -c -std=c99 -pthread A3Nr2AKTUELL.c
pj@linux-7z48:~/bin/KMS2> make
gcc -o prog A3Nr2AKTUELL.o
A3Nr2AKTUELL.o: In function `main':
A3Nr2AKTUELL.c:(.text+0x109): undefined reference to `pthread_create'
A3Nr2AKTUELL.c:(.text+0x122): undefined reference to `pthread_create'
collect2: ld returned 1 exit status
make: *** [prog] Fehler 1
pj@linux-7z48:~/bin/KMS2>


so sieht übrigens meine makefile aus:
Code:
prog: A3Nr2AKTUELL.o 
	gcc -o prog A3Nr2AKTUELL.o 

A3Nr2AKTUELL.o: A3Nr2AKTUELL.c 
		gcc -c A3Nr2AKTUELL.c

hab auch mal versucht in der makefile anstelle von gcc -c A3Nr2AKTUELL.c folgendes einzugeben:
gcc -c std=c99 -pthread A3Nr2AKTUELL.c
und anschließend hab ich in der konsole make ausgeführt.
aber da kam ebenfalls derselbe fehler wie oben beschrieben.

bei openSuse 11.2 ist standardmäßig kein compiler installiert.
hab danach einen c++ compiler und irgendeinen c compiler installiert, weiß jetzt nicht mehr genau welchen.
vielleicht liegt es ja an dem compiler, dass es trotz der eingabe von gcc -c std=c99 -pthread A3Nr2AKTUELL.c nicht funktioniert?
kann das sein? wie kann ich denn nachschauen welche compiler ich installiert hatte?
wie gesagt hab von linux keine ahnung, hab am wochende ein tutorial zur bashprogrammierung und bash skripten gemacht und hab
nicht soviel wissen in diesem bereich, außer dem bisschen was ich dort gelernt hab.
 

Tooltime

Advanced Hacker
blubblub schrieb:
wie kann ich denn nachschauen welche compiler ich installiert hatte?
Du schaust nach welches Paket du installiert hast. Da aber gcc der GNU-Compiler ist kannst du näheres mit gcc --version abfragen.
Code:
gcc --version
gcc (SUSE Linux) 4.4.1 [gcc-4_4-branch revision 150839]
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Probiere es zuerst mal wie ich manuell ohne make-File und gib folgende Befehle direkt in der Konsole ein:

  • gcc -c -std=c99 -pthread A3Nr2AKTUELL.c
    gcc -pthread -o prog A3Nr2AKTUELL.o
Dann sollte ohne Fehlermeldung das Binäry prog erstellt werden.

Wenn das klappt musst du dein Makefile so ändern das diese Befehlszeilen erzeugt werden:
Code:
prog: A3Nr2AKTUELL.o 
   gcc -pthread -o prog A3Nr2AKTUELL.o 

A3Nr2AKTUELL.o: A3Nr2AKTUELL.c 
   gcc -c -std=c99 -pthread A3Nr2AKTUELL.c

Falls du ein einfaches Beispiel für ein Makefile suchst, dann schau mal hier auf Seite 3 rein. Das kann schon etwas mehr als deine Version.

Für größere Projekte sollte man sich mit autoconf und automake beschäftigen, oder alternativen wie cmake, ...
Oder man nimmt gleich eine Entwicklungsumgebung die beim Hinzufügen der Quellcodedateien die entsprechenden Make-Dateien pflegt. Hängt natürlich alles davon ab was du eigentlich vor hast.
 
OP
B

blubblub

Newbie
hey cool es funktioniert jetzt.

@Tootime
hab meine makefile auch hinterher so geändert wie dus gesagt hast und
da gehts natürlich auch. danke für die hilfe.

hab da noch ne frage zu: gcc -pthread -o prog A3Nr2AKTUELL.o
soweit ich die tutorials richtig verstanden hab, wird der compiler gcc mit der option -pthread aufgerufen.
bedeutet diese option, dass die header datei pthread beim kompilieren dazu gelinkt wird?
oder wie muss ich mir das schematisch vorstellen?


und eine weitere frage zu: gcc -c -std=c99 -pthread A3Nr2AKTUELL.c
wieso muss ich hier -std=c99 zusätzlich hinschreiben, warum kann man das nicht weglassen?


@abgdf
wieso muss denn das -c weg?
hab das jetzt so gemacht, wie es Tooltime in seinem letzten beitrag vorgeschlagen hat.
da gibt es auch ein -c und da funktioniert es.
was besagt denn die option -c?
in dem tutorial zu makefiles, das ich mir durchgelesen habe wurde auch immer -c geschrieben.
ich wende das einfach nur so an wies da steht, aber keine ahnung was genau dahinter steckt.

nun wollte ich noch ein benchmark machen und schauen wie lange die ausführung des programms,
dass ich geschrieben habe dauert und dies dann in ein andere datei speichern.
wie man etwas in eine datei schreibt hab ich schonmal kurz angelesen in einem tutorial, das werd ich
denk ich hinkriegen.
aber wie funktioniert das mit der zeitmessung?

mein bashskript sieht zurzeit so aus:
Code:
#!/bin/bash

cd KMS1
echo "A3Nr1AKTUELL"

for(( I=1; $I <= 5; I++))
do
    echo ""
    echo "Ausführung Nr. $I" 
    ./prog
done

echo "Ausführung Ende (A3Nr1AKTUELL)" 
echo ""

##### zweiter abschnitt ####

cd ..
cd KMS2
echo "A3Nr2AKTUELL"

for(( I=1; $I <= 5; I++))
do
    echo ""
    echo "Ausführung Nr. $I" 
    ./prog
done

echo "Ausführung Ende (A3Nr2AKTUELL)" 
echo ""
 

abgdf

Guru
blubblub schrieb:
@abgdf
wieso muss denn das -c weg?
hab das jetzt so gemacht, wie es Tooltime in seinem letzten beitrag vorgeschlagen hat.
da gibt es auch ein -c und da funktioniert es.
was besagt denn die option -c?
in dem tutorial zu makefiles, das ich mir durchgelesen habe wurde auch immer -c geschrieben.
ich wende das einfach nur so an wies da steht, aber keine ahnung was genau dahinter steckt.
Dazu "man gcc":
-c Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.
Wenn du nicht linken willst, mit "-c", sonst ohne "-c".
mein bashskript sieht zurzeit so aus:
Soweit ok, die Variable "I" könnte/sollte man jedoch klein schreiben. Wenn Du von Windows kommst, bist Du vielleicht die Unterscheidung Groß-/Kleinschreibung noch nicht so gewohnt. Unter Linux, und auch im C-Code usw. ist das aber wichtig.
Groß schreibt man vor allem Konstanten (was "I" ja nicht ist).

Gruß
 

Tooltime

Advanced Hacker
Du solltest dir erst einmal den Unterschied zwischen kompilieren und linken klar machen.
Kompilieren:
  • Der Quellcode wird in Maschienencode übersetzt, aber alle Speicheradressen haben noch symbolische Namen. Das gilt für Variablen und Funktionen. Das Ergebnis ist der sogenannte Objektcode
Linken:
  • Jetzt werden die ganzen Objektkodedateien genommen und an einander gehängt. Dabei löst der Linker alle symbolischen Adressen in echte Speicheradressen auf. Erst der Linker kennt nach dem Zusammensetzen die genaue Position von Funktion oder Variable im Speicher. Heraus kommt das was man so ein Programm nennt
Warum macht man das?

  • Größere Projekte verteilt man auf viele Quellcodedateien. Ändert man eine Datei, so muss nur diese eine neu kompiliert aber immer das gesamte Werk neu gelinkt werden. Außerdem kann so Objektcode aus verschiedenen Programmiersprachen zusammengesetzt werden. In gleicher Weise kann man Objektcode (fertige Programmmodule) aus anderen Projekten in sein eigenes einbinden, ohne diese selbst kompilieren zu müssen, die Dinger nennt man Bibliotheken.
Was sind Header-Dateien:
  • Da steht drin welche Funktionen per Bibliothek benutzt werden können, aber nicht in welcher sie sich befinden.
Wie findet der Linker eine Bibliothek:
  • Von alleine findet er keine einzige, jede benutzte Bibliothek muss angegeben werden.

abgdf schrieb:
Wenn du nicht linken willst, mit "-c", sonst ohne "-c".
Und da der zweite gcc-Aufruf (ohne -c) als Eingabedatei den Objektcode erhält, weiß er das nur gelinkt werden muss.

Nur kompilieren --> gcc -c -std=c99 -pthread A3Nr2AKTUELL.c
Nur Linken (Objektcodedateien) --> gcc -pthread -o prog A3Nr2AKTUELL.o
 
Oben