Hi,
ich bin mir nicht ganz sicher ob ich da einen Fehler gemacht habe oder ob ich einen Fehler in den POSIX-Threads (RT-Extension) gefunden habe.
Ich habe mir eine Event-Klasse gebastelt, die mir das Leben ein wenig einfacher machen soll. Knackpunkt: sem_wait() gibt in manchen Fällen -1 (Invalid Value) zurück. Ein aufruf ohne Ctor findet nicht statt. Ich bin kurz davor die Klasse mit nem Conditional Mutex zu implimentieren.
Event.cpp (mit bissl Debug-Code, wie man ihn nicht gestalten sollte *g*)
#include <errno.h>
#include <unistd.h>
#include "OEPlatformEvent.h"
#ifndef errno
extern int errno;
#endif
namespace OE
{
namespace Platform
{
Event::Event(bool initialState, const char* name)
{
switch (sem_init(&event_, 0, initialState ? 1 : 0))
{
case 0:
break;
case EINVAL:
throw "Value exceeds SEM_VALUE_MAX";
case ENOSYS:
throw "Sharing Events between processes is not allowed";
}
}
Event::~Event()
{
sem_destroy(&event_);
}
void Event::set()
{
std::cout << "+" << (void*)&event_ << "|SET" << std::endl;
if (sem_post(&event_) != 0)
throw "Setting Event failed";
}
void Event::reset()
{
while (sem_trywait(&event_) == 0);
}
bool Event::wait(unsigned int waitTime)
{
if (waitTime != OE_INFINITE)
{
for (unsigned int i = waitTime; i != 0; --i)
{
if (tryWait())
return true;
usleep(1000);
}
}
else
{
int v = 0;
sem_getvalue(&event_, &v);
std::cout << "+" << (void*)&event_ << "|" << v << std::endl;
int status = sem_wait(&event_);
if (status == -1)
{
std::cout << "|" << (void*)&event_ << "|" << errno << strerror(errno) << std::endl;
}
std::cout << "-" << (void*)&event_ << "|" << v << std::endl;
return true;
}
return false;
}
bool Event::tryWait()
{
return sem_trywait(&event_) == 0;
}
}
}
Ausgabe:
... kleiner Regressiontest für das Event ...
:EventThread Waiting for event...
+0x80a32a4|0
:Thread Test Setting event
+0x80a32a4|SET
-0x80a32a4|0
:EventThread ...done!
:EventThread TryWait should fail
:Thread Test TryWait should fail
:Thread Test Waiting for event...
+0x80a32a4|0
:EventThread Setting event
+0x80a32a4|SET
-0x80a32a4|0
:Thread Test ...done!
:Thread Test TryWait should fail
:Thread Test Waiting for EventThread
... andere Stelle im Programm ...
+0x80a033a|0
|0x80a033a|22Invalid argument <-- sem_wait() schlägt fehl, das SET sollte danach aufgerufen werden, aber weil das Event nicht blockt: Segfault.
-0x80a033a|0
Ideen?
Grüße,
Christoph
kingruedi schrieb:
cat ist überflüssig :p
grep $DEFINE $DATEI
Und ich dachte immer, Du seist einer dieser "wir catten immer, damit alles konsistent bleibt"-Advokaten.
ja schätze auch mal, dass wo UNIX draufsteht UNIX gemeint ist.
ich hab das auch nur unter Linux benutzt. Für win soll man
g_io_channel_new_file() benutzen, ausserdem steht in der ref., win support
is partially, was immer das heisst.
da musst du selber mal ein wenig stöbern. von win hab ich echt keine ahnung.
ah super....danke.
Jetzt würde mich noch interessieren wozu genau diese Symbole sind oder warum das überhaupt genau macht....ich kann leider nirgendwo literatur dazu finden
Zumal die Rechte des Verzeichnisse auch eine Rolle spielen, wirst du exec* so nicht benutzen können. Da musst du man: fork(2) benutzen, so in etwa:
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int status;
switch(vfork())
{
case -1:
perror("vfork()");
break;
case 0:
exec*_funktion_ausführen
}
wait(&status);
return 0;
}
Was meinst du mit "auslesen"?
Die Binutils (sind auf jedem System installiert, wo auch ein GCC läuft), enthalten eine Menge Tools zum auslesen von Binärdateien. Disassembler, Symbol-Reader, C++-Symbol-Demangler etc. alles vorhanden.
Ansonsten basieren die Binutils auf der Binary File Descriptor library, damit kannst du Symbole auch selbst auslesen. Die Lib scheint aber ein wenig innere Magie zu besitzen, zumindest bin ich neulich beim rumspielen damit ein wenig gescheitert, werd das aber bald wieder in Angriff nehmen
Naja, das kommt immer darauf an was genau du über die Anwendung erfahren willst. Am einfachsten wäre es vermutlich einfach /proc/<pid>/exe auszulesen, dort befindet sich ein Link auf das Binarie. Ansonsten findest du die Comandozeile in /proc/<pid>/cmdline und du könntest den Programmnamen über argv[0] erfahren.
Nachhteil, das procfs ist stark OS abhängig und es wäre natürlich dumm, wenn deine Library eigentlich portabel auf mehreren Unix Systemen läuft, du aber wegen solch einer Sache Inkompatibilitäten erzeugt.
Eine andere Sache ist die, dass argv[0] (der Programm aufruf) relativ unterschiedlich ausfallen kann und die Parameter auch nicht gegen Manipulation geschützt sind.
Hast du dieses Codefragment im Inneren einer Schleifenkonstruktion? Wenn ja, würde es mich nicht wundern
Versuch mal folgendes:
i2c = open(...);
while(!ende)
{
//Lesen, verarbeiten,...
}
close(i2c);
Und ja, zwischen open() und close() bleibt die Datei geöffnet - du kannst sie also auch zwischen mehreren Funktionen herumreichen, um damit zu lesen/schreiben.
Hello,
danke für deine Antwort.
Das Problem was in dem Gentoo Forum steht beschreibt genau mein Problem - leider hiflt die vorgeschlagene Lösung - mit `Linuxshellbefehlen` arbeiten nicht - da meldet MRTG einen Syntaxfehler in der Configfile.
Der Kernel des Systems ist schon ein 2.6er, und die Paketversionen der installierten Software sind eigentlich auch recht aktuell.
Viele Grüße nochmal
socket++ schrieb:
Sovok schrieb:
wo bleiben denn die qualifizierten antworten?
Kannst du die Wahrheit nicht vertragen? Legst du keinen Wert auf guten Code?
ioctl war alles was ich wissen wollte... danke an euch beide
und btw. der code funktioniert auch ohne den aufruf aber is schneller mit
Im Forum findest du hier u. a. ein Beispielprogramm von mir, das die Daten von der seriellen Schnittstelle ausgibt. Wenn du hier printf() durch fprintf() ersetzt (mit deiner TXT-Datei als stream), landen die Ausgaben in deiner Datei.
Martin
Hi,
Ich wollte mir ein kleines Programm erstellen, was alle Daten von STDIN
in eine nonblocking named pipe schiebt. Bei Bedarf sollte ein andere
Programm gestartet werden, welches dann die aktuellen Daten von der PIPE
liest und mit ihnen arbeitet.
Solange das zweite Programm nicht läuft sollen alle Daten die in die PIPE
geschrieben werden, verworfen werden.
Nun hab ich aber ein Problem. So wie ich mir das dachte geht das nicht.
Ich kann nur die Daten aus der pipe lesen, wenn ich den Leseprozess vor dem
Schreibprozess starte. Das ist aber für meine Absichten nicht möglich.
Wie kann ich das machne? Geht das überhaupt mit pipes?
Mit freundlichen Grüßen
Alexander Sulfrian