<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IOException.de &#187; c++</title>
	<atom:link href="http://www.ioexception.de/category/cpp/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ioexception.de</link>
	<description>Ausgewählter Nerdkram von Informatikstudenten der Uni Ulm</description>
	<lastBuildDate>Fri, 13 Jan 2012 07:38:26 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Teamprojekt Humanoid-Roboter (The Birth)</title>
		<link>http://www.ioexception.de/2010/05/30/teamprojekt-humanoid-roboter-the-birth/</link>
		<comments>http://www.ioexception.de/2010/05/30/teamprojekt-humanoid-roboter-the-birth/#comments</comments>
		<pubDate>Sun, 30 May 2010 11:16:52 +0000</pubDate>
		<dc:creator>Sebastian Schimmel</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[robotik]]></category>
		<category><![CDATA[uulm]]></category>
		<category><![CDATA[praktikum]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=544</guid>
		<description><![CDATA[Im Laufe eines Studiums muss man ja diverse Praktika machen. Eines davon steht dieses Semester nun auch bei mir an. Nachdem ich lange überlegt hab, ob für einen Nebenfach Medizin Informatiker nun OS im Eigenbau, Autonomous Underwater Vehicle oder Humanoid-Roboter am besten sei, entschied ich mich für letzteres.
Hierbei geht es um einen kleinen Graupner Humanoiden [...]]]></description>
			<content:encoded><![CDATA[<p>Im Laufe eines Studiums muss man ja diverse Praktika machen. Eines davon steht dieses Semester nun auch bei mir an. Nachdem ich lange überlegt hab, ob für einen Nebenfach Medizin Informatiker nun <em>OS im Eigenbau</em>, <em>Autonomous Underwater Vehicle</em> oder <em>Humanoid-Roboter</em> am besten sei, entschied ich mich für letzteres.</p>
<p>Hierbei geht es um einen kleinen <em>Graupner Humanoiden</em> der Serie RB-1000. Diesem Humanoiden, getauft auf T-1000 aka <em>Arnie</em>, müssen wir in einem Teamprojekt das Gehen beibringen.</p>
<p>Arnie hat 21 Servos, 2 LED-Augen(rot) und einen Microkontroller, der an der Uni eigenständig entwickelt wurde, versehen mit einer Bluetooth-Schnittstelle und einem Gyroskop. In zwei Praktika zuvor wurden zwei Interfaces entwickelt, das eine in MatLab und das andere in C/C++. Derzeit können wir uns noch nicht ganz entscheiden, welches von beiden wir verwenden werden. Allerdings ist mir das C/C++ gerade noch lieber, da es weniger Probleme bereitet und von uns in – welch Einfalssreichtum – Skynet umbenannt wurde. Das schöne dabei ist, dass man beispielsweise ein Bashscript schreiben kann für die Ansteuerung und dann das ganze einfach an Skynet pipen kann.</p>
<p>Bisher bestand unsere Tätigkeit darin, Arnie erst einmal komplett zu entrümpeln. Wir haben unnötige Meter an Servokabel entfernt, die Stromversorgung neu angeschlossen, neue Schalter angebracht, die Batterie im Brustkorb durch ein passendes Netzteil ersetzt, was uns die Handhabung um mindestens 120% verbessert, die Interfaces gestestet und vorbereitet. Demnächst werden wir auch noch eine kleine Justierungsstation basteln, damit man ihn vor Inbetriebnahme immer optimal einstellen kann.</p>
<p>Natürlich haben wir auch schon ordentlich an ihm getestet was er kann und wie es geht. Hier sieht man ihn, wie er winkt.</p>
<p><object width="600" height="450"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=12148131&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=12148131&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="600" height="450"></embed></object></p>
<blockquote><p>This is only the beginning&#8230;.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2010/05/30/teamprojekt-humanoid-roboter-the-birth/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Einführung in C Linker, Compiler, Preprocessor und mehr</title>
		<link>http://www.ioexception.de/2009/12/05/einfuhrung-in-c-linker-compiler-preprocessor-und-mehr/</link>
		<comments>http://www.ioexception.de/2009/12/05/einfuhrung-in-c-linker-compiler-preprocessor-und-mehr/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 17:39:04 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[betriebssysteme]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Compiler]]></category>
		<category><![CDATA[Linker]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=363</guid>
		<description><![CDATA[Die Einführungsvorlesung &#8220;Computer Science 50: Introduction to Computer Science I&#8221; von Harvard College hat sehr gut gemachte Vorlesungen als Flash Video online, insbesondere die Vorlesungen über die C Grundlagen sind wirklich schön. 
Meine Empfehlungen:

Week 8. Huffman coding. Preprocessing. Compiling. Assembling. Linking. CPUs. Ant-8. 

Vorlesung 1
Vorlesung 2


Week 9. Writing secure C code. Buffer overruns. Dangerous functions.

]]></description>
			<content:encoded><![CDATA[<p>Die Einführungsvorlesung <a href="http://cs50.tv/">&#8220;Computer Science 50: Introduction to Computer Science I&#8221;</a> von <a href="http://en.wikipedia.org/wiki/Harvard_College">Harvard College</a> hat sehr gut gemachte Vorlesungen als Flash Video online, insbesondere die Vorlesungen über die C Grundlagen sind wirklich schön. </p>
<p><strong>Meine Empfehlungen:</strong></p>
<ul>
<li>Week 8. Huffman coding. Preprocessing. Compiling. Assembling. Linking. CPUs. Ant-8. </p>
<ul>
<li><a href="http://www.courses.fas.harvard.edu/~cs50/play/podcasts/2007/lectures/week8w.flv">Vorlesung 1</a></li>
<li><a href="http://www.courses.fas.harvard.edu/~cs50/play/podcasts/2007/lectures/week8f.flv">Vorlesung 2</a></li>
</ul>
</li>
<li>Week 9. Writing secure C code. Buffer overruns. Dangerous functions.
<ul>
<li><a href=http://www.courses.fas.harvard.edu/~cs50/play/podcasts/2007/lectures/week9m.flv">Vorlesung 1</a></li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/12/05/einfuhrung-in-c-linker-compiler-preprocessor-und-mehr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ein einfacher Scheduler in C++ — Teil 2: Scheduler</title>
		<link>http://www.ioexception.de/2009/06/23/ein-einfacher-scheduler-in-c-%e2%80%94-teil-2-scheduler/</link>
		<comments>http://www.ioexception.de/2009/06/23/ein-einfacher-scheduler-in-c-%e2%80%94-teil-2-scheduler/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 20:05:06 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[betriebssysteme]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[datenstrukturen]]></category>
		<category><![CDATA[pthread]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=123</guid>
		<description><![CDATA[Die zentrale Frage bei der Implementierung des Schedulers ist die Frage nach der Datenstruktur in der die   Tupel gehalten werden. Der Scheduler soll, gemäß der SJF Strategie, immer das Tupel auswählen dessen Joblänge  am kürzesten ist. Für solche eine Problemstellung eignet sich die Datenstruktur std::set bzw. std::multiset parametrisiert auf std::pair am Besten. [...]]]></description>
			<content:encoded><![CDATA[<p>Die zentrale Frage bei der Implementierung des Schedulers ist die Frage nach der Datenstruktur in der die <img src="http://l.wordpress.com/latex.php?latex=%20%28%20%5Ctext%7BId%7D%2C%20%20%5Ctext%7BJobl%5C%22%7Ba%7Dnge%7D%29%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" ( \text{Id},  \text{Jobl\"{a}nge}) " style="vertical-align:-20%;" class="tex" alt=" ( \text{Id},  \text{Jobl\"{a}nge}) " />  Tupel gehalten werden. Der Scheduler soll, gemäß der SJF Strategie, immer das Tupel<img src="http://l.wordpress.com/latex.php?latex=%20%28%20i%2C%20j%29%20&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title=" ( i, j) " style="vertical-align:-20%;" class="tex" alt=" ( i, j) " /> auswählen dessen Joblänge <img src="http://l.wordpress.com/latex.php?latex=j&#038;bg=FFFFFF&#038;fg=000000&#038;s=0" title="j" style="vertical-align:-20%;" class="tex" alt="j" /> am kürzesten ist. Für solche eine Problemstellung eignet sich die Datenstruktur <code>std::set</code> bzw. <code>std::multiset</code> parametrisiert auf <code>std::pair</code> am Besten. Jedoch ist zu beachten dass die Sortierung bei <code>std::pair</code> normalerweise auf dem ersten Element, also bei uns auf der ThreadId basiert. Daher müssen wir den Vergleichsoperator des <code>std::multiset</code> mit unserem eigenen Operator überschreiben. </p>
<pre class="brush: cpp;">
/*
Scheduler.h
*/

/*
this struct is used to have a different compare operator for std::pair in my std::multiset. I have to compare the second argument of pair!
*/
struct compareBySecond {
  bool operator() (const std::pair&lt;int,int&gt;&amp; a, const std::pair&lt;int,int&gt;&amp; b) const
  {return (a).second&lt;(b).second;}
};

/*
my scheduler class, schedules the requests
*/

class Scheduler{

  public:
    [  ... ]

  private:
    //multiset holds all pairs with (thread,job)
    std::multiset&lt; std::pair&lt;int,int&gt; , compareBySecond &gt; jobs;

    [  ... ]

};
</pre>
<p>Als Synchronisationselemente kommen normale RW-Locks und Condition-Variablen zur Anwendung, auf diese Standardelemente wird hier nicht weiter eingegangen. Guten Beispielcode für diese Elemente findet sich in den Qt3.3-Quellen (z.B.: <a href="http://doc.trolltech.com/4.5/qreadwritelock.html">QReadWriteLock</a>). </p>
<p>Die einzige Methode die von den Anfragethreads ausgeführt wird ist <code>Scheduler::enqueue(int thread, int length)</code> (siehe <a href="http://www.ioexception.de/2009/06/22/ein-einfacher-scheduler-in-c-teil-1-rahmenprogramm/">Teil 1</a>). Bemerkenswert ist hier nur der letzte Aufruf, da wir ja immer eine möglichst volle Queue gewährleisten wollen wartet der Scheduler darauf dass er Jobs erst auswählt, wenn die Queue voll ist oder eine volle Queue nicht mehr erreicht werden kann. Hierzu ist die Condition-Variable<code> cv_queuefull</code> nötig auf die beim Überprüfen der Queue gewartet wird. </p>
<pre class="brush: cpp;">

/*
enqueues a job
*/
void  Scheduler::enqueue(int thread, int length){

  //wait if queue is full or thread has already job in queue
  while(isQueueFull() || threadHasRequestInQueue(thread)){
    cv-&gt;wait();
  }

  //new pair for enqueueing
  std::pair&lt;int,int&gt; tmp(thread,length);

  //lock and insert in queue
  rw-&gt;lockWrite();
  jobs.insert(tmp);
  rw-&gt;unlockWrite();

  //we did it!
  std::cout &lt;&lt; &quot;requester &quot; &lt;&lt; thread &lt;&lt; &quot; joblength &quot; &lt;&lt; length &lt;&lt; std::endl;

  //signal scheduler thread that thread is now maybe full
  cv_queuefull-&gt;signal();
}
</pre>
<p>Die beiden hier noch verwendeten Methoden <code>bool Scheduler::isQueueFull()</code> und <code>bool Scheduler::threadHasRequestInQueue(int thread)</code> sind aus Implementierungssicht trivial. </p>
<p>Die wichtigste Methode in der die eigentlichen Jobs &#8220;abgearbeitet&#8221; werden ist <code>Scheduler::processNextJob()</code>, hier muss zunächst überprüft werden ob die Queue bereit ist. Dies geschieht in  <code>Scheduler::QueueReady()</code> und ist weiter unten erläutert. Für die Auswahl des nächsten Jobs mit der kürzesten Joblänge reicht es das erste Element des Sets zu entnehmen, dies ist nach der von uns definierten Ordnung im Set automatisch der Job mit der kürzesten Laufzeit. Nach dem Abarbeiten wird der Job aus der Queue gelöscht. Falls gerade ein Thread darauf wartet einen Job zu enqueuen dem es vorher nicht möglich war zu enqueuen da er schon einen Job in der Queue hatte wird dieser zum Schluss noch aufgeweckt. </p>
<pre class="brush: cpp;">
/*
processes the next job
*/
void  Scheduler::processNextJob(){
  //is queue ready?
  QueueReady();

  //get job
  rw-&gt;lockRead();
  std::pair&lt;int,int&gt; tmp = *( jobs.begin());
  rw-&gt;unlockRead();

  //process .......... :-)
  std::cout &lt;&lt; &quot;service requester &quot; &lt;&lt; tmp.first &lt;&lt; &quot; joblength &quot; &lt;&lt; tmp.second &lt;&lt; std::endl;

  //delete from queue
  rw-&gt;lockWrite();
  jobs.erase(jobs.find(tmp));
  rw-&gt;unlockWrite();

  //wake up all guys that wait on enqueuing
  cv-&gt;signalAll();
}
</pre>
<p>Für die Überprüfung ob die Queue bereit ist, sind zwei Bedingungen nötig: Ersten muss die Queue voll sein, siehe Annahmen. In dem Fall dass schon Threads beendet wurden kann es passieren dass die Queue nicht voll werden kann. In diesem Fall soll der Scheduler trotz nicht voller Queue seine Arbeit aufnehmen. Hier wäre noch Optimierungspotential gegeben, da nicht garantiert wird dass die Queue in momentanen Zustand der Threads immer so voll wie möglich ist. </p>
<pre class="brush: cpp;">
/*
checks if queue is ready
*/
void Scheduler::QueueReady(){
  while(!isQueueFull() &amp;&amp; (jobs.size() &lt; nrOfThreads) ){
    //wait if our queue is not full or some threads are already dead, thus we can proceed if #threads&lt;Queuesize
    cv_queuefull-&gt;wait();
  }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/06/23/ein-einfacher-scheduler-in-c-%e2%80%94-teil-2-scheduler/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ein einfacher Scheduler in C++ &#8212; Teil 1: Rahmenprogramm</title>
		<link>http://www.ioexception.de/2009/06/22/ein-einfacher-scheduler-in-c-teil-1-rahmenprogramm/</link>
		<comments>http://www.ioexception.de/2009/06/22/ein-einfacher-scheduler-in-c-teil-1-rahmenprogramm/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 16:13:29 +0000</pubDate>
		<dc:creator>Raimar Wagner</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[betriebssysteme]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[pthread]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=108</guid>
		<description><![CDATA[Der hier vorgestellte Scheduler soll am Ende folgende Rahmenbedingungen erfüllen:

Jeder Thread darf nur maximal eine Anfrage in der Warteschlange haben.
Ein Thread stoppt falls alle seine Anfragen bearbeitet wurden.
Der Scheduler arbeitet nach dem SJF (Shortest Job First) Verfahren
Die Warteschlangengröße muss beim Programmstart festlegbar sein

Als Eingabe erhält das Programm die Warteschlangenlänge und eine Liste von Eingabedateien. Jede [...]]]></description>
			<content:encoded><![CDATA[<p>Der hier vorgestellte Scheduler soll am Ende folgende Rahmenbedingungen erfüllen:</p>
<ul>
<li>Jeder Thread darf nur maximal eine Anfrage in der Warteschlange haben.</li>
<li>Ein Thread stoppt falls alle seine Anfragen bearbeitet wurden.</li>
<li>Der Scheduler arbeitet nach dem <a href="http://de.wikipedia.org/wiki/Shortest-Job-Next">SJF (Shortest Job First)</a> Verfahren</li>
<li>Die Warteschlangengröße muss beim Programmstart festlegbar sein</li>
</ul>
<p>Als Eingabe erhält das Programm die Warteschlangenlänge und eine Liste von Eingabedateien. Jede Eingabedatei entspricht einem anfragenden Thread und beinhaltet eine Liste von Nummern die die Joblänge symbolisieren sollen. </p>
<p>Der erste Teil besteht aus der Implementierung des Rahmenprogramm der sich der später zu implementierenden Schedulerklasse bedient.<br />
Der erste Teil der <code>main()</code> Methode besteht aus den Auslese- und Initialisierungaufrufen. Insbesondere wird der Scheduler mit der Anzahl der Threads und der maximalen Warteschlangenlänge initialisiert. </p>
<pre class="brush: cpp;">

  //get queue-size
  int maxQueue=atoi(argv[1]);

  if(maxQueue&lt;=0) {
     std::cout &lt;&lt; &quot;min. queue size is 1&quot; &lt;&lt; std::endl;
     return 0;
  }

  //vector so store filenames
  std::vector&lt;std::string&gt; files;

  //count #threads
  int numOfThreads=0;

  //save filenames
  for (int i = 2; i &lt; argc; i++) {
     files.push_back(std::string(argv[i]));
     //every file is one thread
     numOfThreads++;
  }

  //create new scheduler
  scheduler= new Scheduler(maxQueue, numOfThreads);  

  //just temp storage for reading file
  std::string line;

  //iterate through parameters
  for(int i = 0; i&lt; argc-2; i++){
    //new parameter =&gt; new thread
    jobs.push_back(std::vector&lt;int&gt;());
    //open file
    std::ifstream myfile(files.at(i).c_str());
    if (myfile.is_open())
    {
      //push all job lengthes in vector
      while (! myfile.eof() )
      {
        std::getline (myfile,line);
        (jobs.at(i)).push_back(atoi(line.c_str()));
      }
      //close file
      myfile.close();
    }
  }
</pre>
<p>Im nächsten Schritt müssen alle anfragenden Threads gestartet werden, in diesem Fall kommen einfache <a href="http://en.wikipedia.org/wiki/POSIX_Threads">pthreads</a> zur Anwendung. Zu beachten ist dass <code>&#038;run_thread</code> der Funktionspointer auf die sogenannte run-Methode darstellt. </p>
<pre class="brush: cpp;">

   //array of threads
   pthread_t th[numOfThreads];

   //array of int* to transfer thread nr. to thread
   int* numbers[numOfThreads];

   for (int i = 0; i &lt; numOfThreads; i++) {
      //save thread nr.
      numbers[i]=new int(i);
      //create thread and transfer parameter
      pthread_create (&amp;th[i], NULL, &amp;run_thread, numbers[i]);
   }
</pre>
<p>Im <code>main()</code> Thread läuft auch der Scheduler der solange Anfragen abarbeitet bis die Warteschlange leer ist. Danach muss um ein sauberes Programmende zu gewährleisten noch auf alle Threads gewartet werden. </p>
<pre class="brush: cpp;">
   //process jobs until Queue is empty
   while(!scheduler-&gt;isQueueEmpty()){
       scheduler-&gt;processNextJob();
   }

   //wait until all threads are finished
   for (int i = 0; i &lt; numOfThreads; i++){
      pthread_join (th[i], NULL);
   }

   return 0;
</pre>
<p>Die von den Anfragethreads ausgeführte Methode <code>run_thread(void *number)</code> hat ein paar Stolperfallen; hier ist zu beachten dass an <code>pthreads </code>übergebene Funktionen nur <code>void*</code> Pointer als Parameter haben dürfen, deshalb muss auch innerhalb der Methode die Threadnummer wieder auf <code>int*</code> gecastet werden. Nach dem einreihen aller Anfragen in die Warteschlange des Schedulers kann sich der Thread beenden. </p>
<pre class="brush: cpp;">
static void* run_thread (void *number) {

   for(unsigned int i=0; i&lt; (jobs.at(*( (int*) number))).size()-1;i++){
    //enqueue all jobs in waiting queue
    scheduler-&gt;enqueue(*( (int*) number), (jobs.at(*( (int*) number))).at(i) );
   }
   //all jobs are enqueued =&gt; thread has done his work
   scheduler-&gt;decreaseThreads();
   pthread_exit (NULL);
}
</pre>
<p>In nächsten Teil wird detailliert auf die Funktionsweise und den Aufbau eines des hier benutzten Schedulers eingegangen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/06/22/ein-einfacher-scheduler-in-c-teil-1-rahmenprogramm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

