Threads!
-
@heiner: Das ist Linux/Unix (eigentlich ja POSIX *g*) spezifisch.
-
ich verschiebe den Thread mal ins Unix Forum, die haben da ahnung von
Linux/Unix
-
Habe noch eine weitere Frage: nämlich zu fork(). Hier word doch ein sogenannter "Kindprozess" gestartet, ist dieser vergleichbar mit einem Thread? Allerdings wartet der "Vaterprozess" doch bis sein Kind fertig ist. Was fü einen nutzen hat fork() den dann? Der Vater kann die Aufgabe des Prozesses dovh auch einfach selber ausführen, oder? Lese fork immer im Zusammenhang mit exec() aber dies konnte der Hauptprozess ja auch selber ausführen.
Acchja und was ist vFork()Vielen Dank!! heiner
-
Original erstellt von <heiner>:
Allerdings wartet der "Vaterprozess" doch bis sein Kind fertig ist.
Acchja und was ist vFork()Also: Bei fork() gabelt (daher der Name "fork") sich der Prozess: Es ensteht eine 1:1-Kopie des Parent-Process als Child-Process. Beide laufen unabhängig voneinander (warten also auch nicht auf das Beenden des anderen). Sobald einer der Prozesse schreibend auf seinen Speicher zugreift, wird dieser Speicherbereich kopiert, sodass er für den anderen Prozess unverändert bleibt (das nennt man "copy on write" Prinzip). Es stehen beiden Prozessen also alle bis zum fork()-Aufruf angelegten Variablen, geöffneten Dateien usw. zur Verfügung, ein Datenaustausch über Variablen o.ä. ist aber nicht möglich! (Es sei denn, man richtet Shared Memory ein).
vfork() ist unter Linux identisch mit fork().
Wenn du mehr darüber wissen willst, werf mal einen Blick in mein Buch "C und Linux"
Martin
-
Sehr cool Danke. Noch ne Frage sehe ich das richtig: Der geforkte Prozess "startet" ab der code Zeile wo der fork() Aufruf statt findet, und es werdern alle vorher alle vorher angelegten Variablen und objekte Kopiert(falls sie benötigt werden. Kann man die zwei sprozesse den irgendwie auseinnaderhalten, sodass in etwa folgendes möglich wäre:
if(child_process) child_process.destroy();
-
http://www.mcsr.olemiss.edu/cgi-bin/man-cgi?fork+2
letzter Abschnitt...
-
Original erhttp://stellt von <heiner>:
**Ich muß für eine Aufgabe pThreads. mutexe, etc implementieren. Kennt da jemand ein schönes Tutorial für?
**Falls du Programmbeispiele suchst, dann schau dir mal die Examples an die es zu folgenden beiden Bücher gibt:
Bradford et.al.: Pthreads Programming - A POSIX Standard for Better Multiprocessing
http://sources.redhat.com/pthreads-win32/[ Dieser Beitrag wurde am 06.01.2003 um 18:19 Uhr von Descartes editiert. ]
-
Original erstellt von <heiner>:
Kann man die zwei sprozesse den irgendwie auseinnaderhaltenDer fork() Aufruf liefert dir die Prozess-Id des Kind Prozesses zurück.
In der Regel macht man nach dem fork() Aufruf einen switch/case auf diese Prozess-Id.
Ist der von fork() zurückgegeben Wert <0 dann ist der fork() fehlgeschlagen.
Ist der Returnwert > 0 dann befindest du dich im Vater Prozess (weil fork() dir ja die Prozess-Id des Kindes liefert).
Ist der Returnwert = 0 dann befindest du dich im Kind Prozess.kleines Beispiel:
#include <stdio.h> /* printf() fprintf() */ #include <unistd.h> /* fork() */ #include <sys/types.h> #include <sys/wait.h> /* wait() */ int main() { switch(fork()) { case -1 : { fprintf(stderr, "Fehler beim Fork-Aufruf\n"); exit(1); } case 0 : /* Sohn Prozess */ { /* * ... Hier schreibst du rein was der Kind Prozess machen soll ... */ printf("SOHN: Hallo Welt\n"); exit(0); } default : /* Vater Prozess */ { int status; /* * ... Hier schreibst du rein was der Vater Prozess machen soll ... */ printf("VATER: Hallo Welt\n"); wait(&status); /* auf Beendigung des Sohn Prozess warten */ } } return 0; }
[ Dieser Beitrag wurde am 06.01.2003 um 18:31 Uhr von Descartes editiert. ]
-
Kleines Beispiel für Threads gefällig?
#include <stdio.h> /* printf() fprintf() */ #include <string.h> /* strncpy() */ #include <pthread.h> /* pthread_mutex_t pthread_t pthread_create() pthread_join() pthread_mutex_lock() pthread_mutex_unlock() */ /* struct fuer die Parameteruebergabe der Threads an die Thread-Funktion */ typedef struct { int nummer; char text[20]; } argument_t; void mein_thread(void*); /* unsere Mutex Variable */ pthread_mutex_t mut=PTHREAD_MUTEX_INITIALIZER; int main() { pthread_t thread1, thread2; argument_t arg1, arg2; arg1.nummer=1; strncpy(arg1.text, "Hallo Welt\0", 20); arg2.nummer=2; strncpy(arg2.text, "Hallo Welt\0", 20); /* Thread 1 erzeugen */ if(0!=pthread_create( &thread1, NULL, (void*)mein_thread, (void*)&arg1)) { fprintf(stderr, "Fehler bei pthread_create() [thread1]\n"); exit(1); } /* Thread 2 erzeugen */ if(0!=pthread_create( &thread2, NULL, (void*)mein_thread, (void*)&arg2)) { fprintf(stderr, "Fehler bei pthread_create() [thread2]\n"); exit(1); } /* Warten, bis die beiden Threads fertig sind */ if(0!=pthread_join(thread1, NULL)) { fprintf(stderr, "Fehler bei pthread_create() [thread1]\n"); exit(1); } if(0!=pthread_join(thread2, NULL)) { fprintf(stderr, "Fehler bei pthread_create() [thread2]\n"); exit(1); } return 0; } void mein_thread(void* arg) { argument_t* args=(argument_t*)arg; pthread_mutex_lock(&mut); printf("THREAD %i: %s\n",args->nummer , args->text); sleep(2); pthread_mutex_unlock(&mut); };
-
Original erstellt von Martin G:
vfork() ist unter Linux identisch mit fork().angeblich ist das wohl nicht mehr so, obwohl ich den genauen Grund nicht kenne und auch nicht die Implementierung im Kernel angeguckt habe (stand in dem aktuellen Vortrag von Felix von Leitner)
-
interessant zum thema fork()/vfork() und warum exit() evil ist,
ist auch das hier:http://www.faqs.org/faqs/unix-faq/programmer/faq/
@kingruedi:
wo hast du denn den vortrag von fefe gefunden ?
oder hat er das auf dem 19c3 erzählt ??
-
direkt bei den News
-
ach das war das
( war zu faul ins pdf zu gucken )
thanx
-
Super cool! und vielen Dank! obwohl mir doch jeden Tag klarer wird was jave doch für eine schöne Standardisierte Sprache ist.
Mal noch eine Frage: Warum wird den in der ganzen Kernel Ecke und wenn es um Systemnahe Funktionen wie Threads geht immer noch mit diesem fürchterlichen c-Krams rumgemacht. Es ist wohl noch ein wenig performanter als c++ und keiner hat wohl Lust den gesammten Linux Kernel umzu schreiben, aber langsam könnte man sich doch mal der OOP Richtung zu wenden. Wenn ich so ein langen c code Anschauen muss wird es mir in der Magengegend doch ein wenig übel. Wie schlecht der code alleine schon lebar ist alles durcheinander da keine gekapseten Objekte, viel mehr code als in einer Hochsprache, keine Schachtelungen von Funktionen => absolut ungeschmeidig. Und das schlimmste daran ist: Die Leute sn der Uni fahren total drauf ab: Statt mit Objekten und so genialen Errungenschafften wie streams etc. zu arbeiten wird lieber Systemnahe programmiert.
Sorry fürs abschweifen aber das musste einfach mal raus.
-
Naja der Kernel ist schon ganz sauber programmiert IMHO, in der Kernel Mailinglist FAQ steht aber warum C anstelle C++
-
Original erstellt von <heiner>:
**Super cool! und vielen Dank! obwohl mir doch jeden Tag klarer wird was jave doch für eine schöne Standardisierte Sprache ist.Mal noch eine Frage: Warum wird den in der ganzen Kernel Ecke und wenn es um Systemnahe Funktionen wie Threads geht immer noch mit diesem fürchterlichen c-Krams rumgemacht. Es ist wohl noch ein wenig performanter als c++ und keiner hat wohl Lust den gesammten Linux Kernel umzu schreiben, aber langsam könnte man sich doch mal der OOP Richtung zu wenden. Wenn ich so ein langen c code Anschauen muss wird es mir in der Magengegend doch ein wenig übel. Wie schlecht der code alleine schon lebar ist alles durcheinander da keine gekapseten Objekte, viel mehr code als in einer Hochsprache, keine Schachtelungen von Funktionen => absolut ungeschmeidig. Und das schlimmste daran ist: Die Leute sn der Uni fahren total drauf ab: Statt mit Objekten und so genialen Errungenschafften wie streams etc. zu arbeiten wird lieber Systemnahe programmiert.
Sorry fürs abschweifen aber das musste einfach mal raus.**
Das gehört zwar eigentlich nicht in diesen Thread, aber da du dieses Thema schon mal angesprochen hast: Ich habe schon jede Menge in ANSI-C programmiert (sowohl hardware-nahe Programme als auch völlig systemunabhängige Berechnungsprogramme) und mir von einiger Zeit mal C++ und Java angeschaut. Ich kann (für die Programme, die ich schreibe) beim besten Willen nicht den Vorteil entdecken. Was ist z.B. an
System.out.println("Hello!");
einfacher als an
printf("Hello!\n");
Oder was ist an
len = mein_string.length();
besser lesbar als
len = strlen(mein_string);
Umgekehrt ist bei ANSI-C ziemlich klar, was der Compiler aus dem Quelltext macht. Aber was passiert, wenn man bei C++ dynamisch neue Objekte anlegt, die auch Funktionen enthalten? Wird dann neben dem Speicher für die Variablen innerhalb der Objekte auch Speicher für die Funktionen neu belegt, ist also die gleiche Funktion dann mehrfach im Speicher vorhanden?
Nebenbei bemerkt kann man auch mit ANSI-C objektorientiert programmieren. Die GUI-Bibliothek libxview z.B. ist in Standard-C (nicht einmal ANSI-C) geschrieben und trotzdem objektorientiert, d.h. jedes grafische Element - ob Fenster oder Button - ist ein XView-Objekt (alle vom Typ "Xv_object") mit Grundeigenschaften (z.B. Position) und speziellen Eigenschaften (z.B. Fußzeile beim Fenster).
Sicher, für Betriebssystemunabhängige Programme ist Java sicher die bessere Lösung, aber wenn ich bei meinem Linux bleibe, ist mir ANSI-C noch am liebsten.
Martin
-
die Funktionen werden nicht immer wieder kopiert! Mit C kann man auch OO programmieren, aber versuch das mal in C hinzubekommen
template<class T> class basic_class { T test_; public: inline basic_class(const T& obj) : test_(obj) { } inline basic_class(const basic_class<T>& obj) : test_(obj.test_) { } inline virtual ~basic_class() { } inline const T &test(void) const { return test_; } inline void test(const T& obj) { test_=obj; } template<class charT, class traits=std::char_traits<charT> > inline virtual basic_ostream<charT,traits> &print(basic_ostream<charT,traits> &out) const { return (out << test_); } }; template<class T> basic_class<T> operator+(const basic_class<T>& obj, const basic_class<T>&op) { return basic_class<T>(obj.test()+op.test()); } template<class T, class A> class derived_class : public basic_class<T> { A atest_; public: derived_class(const A& obja, const T& objt) : basic_class(objt), atest_(obja) { } inline void atest(const A& obj) { atest_=obj; } inline const A &atest(void) const { return atest_; } inline virtual basic_ostream<charT,traits> &print(basic_ostream<charT,traits> &out) const { return (out << atest_ << test_); } } template<class A, class T> derived_class<A,T> operator+(const derived_class<A,T>& obj, const derived_class<A,T>&op) { return basic_class<A,T>(obj.atest()+op.atest(),obj.test()+op.test()); }
C++ hat schon vorteile!
-
Original erstellt von Martin G:
**
System.out.println("Hello!");einfacher als an
printf("Hello!\n");
Oder was ist an
len = mein_string.length();
besser lesbar als
len = strlen(mein_string);
**
Schlechtes Beispiel. Schreibe mal den Ansi c-code auf welcher zu diesem Ausdruck äquivalent ist:
string substr = "Hallo"; cout << "Länge des Teilstrings: " << mein_string.substring(mein_string.find(substr), substr.length()) << endl;
Ist zwar auf den ersten Blick nicht einfach zu lesen aber doch absolut vertändlich. String manipulationen zu implementieren ist mit c eine sehr langwierige geschichte, IMHO völlig unakzeptabel.
Oder was hälst du von str1 + str2; //kurz, absolut naheliegend, Perfekt!
Ich weiss nicht warum du gerade ein bsp mit strings genommen hast. Die String Behandlung ist wohl eines der allergrößten Mankos von c.
[ Dieser Beitrag wurde am 10.01.2003 um 16:27 Uhr von blauton.com editiert. ]
[ Dieser Beitrag wurde am 10.01.2003 um 16:31 Uhr von blauton.com editiert. ]
-
außerdem kann std::string ziemlich genial implementiert werden, so dass es für n gleiche Strings nur 1 Kopie im Speicher gibt! Außerdem sind die Container Klassen super praktisch und Templates generell!
-
Original erstellt von <heiner>:
obwohl mir doch jeden Tag klarer wird was jave doch für eine schöne Standardisierte Sprache ist.:o
java ist NICHT standardisiert, ganz im Gegensatz zu C und C++