Menü aufrufen
Toggle preferences menu
Persönliches Menü aufrufen
Nicht angemeldet
Ihre IP-Adresse wird öffentlich sichtbar sein, wenn Sie Änderungen vornehmen.
Version vom 12. August 2009, 21:17 Uhr von Penner (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „= VirtualBox, PPTP = Der Zugang zum Sternwartenetzwerk soll in Zukunft standardmäßig über die offizielle VPN-Adresse erfolgen. Dazu wird ein PPTP-Tunnel zu Mon…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

VirtualBox, PPTP

Der Zugang zum Sternwartenetzwerk soll in Zukunft standardmäßig über die offizielle VPN-Adresse erfolgen. Dazu wird ein PPTP-Tunnel zu Mond aufgebaut und dabei erhält man eine offizielle Adresse. Die kann wechseln, daher muss DynDns eingesetzt werden.

Die offizielle Adresse kann man gleich noch für 100 andere Sachen verbraten. Grundsätzlich sollen alle Dienste aber über SSH abgesichert sein. So können wir alles Mögliche basteln und trotzdem in Ruhe schlafen. Denkbare Dienste:

  • OpenVPN
  • Webserver (u.a. Wiki]
  • SSH zum Perseiden

Gatewayrechner

Im Prinzip könnte der Perseid gleich selbst den Tunnel aufrechterhalten. Dabei gibt es zwei Probleme:

  • Der Perseid hat dann eine völlig offene IP-Adresse ohne die Möglichkeit, eine Firewall davorzustellen und auf ihm laufen prinzipiell alle möglichen und unmöglichen Netzwerkdienste. Er müsste sich also selbst mittels Iptables vor Spaßvögeln aus dem Internet schützen.
  • Wie sollte der Perseid Antwortpakete schicken, die seine Kommunikation über die offizielle Adresse betreffen? Sein Standardgateway geht über das NAT-des FBN und das soll asu diversen Gründen auch so bleiben. Im Prinzip könnte man wahrscheinlich nur die passenden Pakete über den Mond routen. Ich weiß erstens nicht wie das geht und zweitens erscheint mir das ganz furchtbar unsauber.

Die Lösung ist ein separater Gatewayrechner. Der kann im Perseid als virtuelle Maschine leben und braucht nur 64 MB RAM, wenn ich ein ein ganz normales Ubuntu in der Serverinstallation verwende. Der wird über die host-only-Variante von Virtualbox angeschlossen und damit kann der Perseid recht gut kontrollieren, was der Gatewayrechner darf und was nicht. In diesem Artikel ist beschrieben, wie man das mittel Host-Interfaces und tunectl machen kann.

Paralleles Auslesen von diversen Sensoren und Zusammenbauen der Daten

Verschiedene Prozesse

Die Kommunikation könnte man über Pipes, Fifos, Shared-Memory, Message-Queues, TCP (Sockets) machen, im Prinzip auch mit MPI.

  • MPI ist Mist, weil man dann immer ein MPI-System braucht
  • Message Queues sind im Prinzip cool, praktisch aber viel zu kurz und für zu kleine Datenmengen gedacht (10 Messages a 8kB ist Standard unter Linux). Dafür soll das halt sehr schnell sein (im L1-Cache bleiben etc).
  • Pipes, Fifos ist halt ein bisschen fummelig. TCP keine Ahnung
  • SHMem ist eigentlich ziemlich ok. Man muss natürlich von Hand synchronisieren. Das ist eigentlich auch kein Ding weiter. Wenn man einmal Zugriff auf den gemeinsamen Speicherbereich hat, sollte das nicht schwieriger sein als mit OpenMP (s.u.).

Verschiedene Threads

Nachteil ist, dass die einzelnen Ausleseprozesse nicht gegeneinander geschützt sind.

OpenMP

Dafür gibt es die nahezu triviale Variante mit OpenMP. Der geringe Aufwand könnte die eher theoretischen Nachteile durchaus wieder wettmachen, finde ich. Ich stelle mit das ungefähr so vor:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <omp.h>
#include <unistd.h>

using namespace std;
int showAction; 

/* Das ist eine etwas missbräuchliche aber immer noch sehr einfache Verwendung
  von OpenMP zur Arbeit mit Threads. Auf alle Fälle ist es schön
  einfach. Evtl. müssen die Jobs das Lesen nicht in einer critical Section
  machen aber es wird hier nichts schaden.
*/

int job1(void)
{
 for(;;)
 {
#pragma  critical
  int sAct=showAction;
  if (sAct&1) cout << "1";
  cout.flush();
  usleep(5000); // nominell 5 ms
 }
}

int job2(void)
{
 for(;;)
 {
  #pragma  critical
  int sAct=showAction;
  if (sAct&2) cout << "2";
  cout.flush();
  usleep(5000); // 5 ms
 }
}

int job3(void)
{
 for(;;)
 {
  #pragma  critical
  int sAct=showAction;
  if (sAct&4) cout << "3";
  cout.flush();
  usleep(5000); // 5 ms
 }
}

int main()
{
 int nthreads, tid;
 omp_set_nested(1);

/* Fork a team of threads with each thread having a private tid variable */
#pragma omp parallel private(tid) num_threads (4)
  {

  /* Obtain and print thread id */
  tid = omp_get_thread_num();
  printf("Hello World from thread = %d\n", tid);
  switch (tid)
  {
   case 1: job1(); break;
   case 2: job2(); break;
   case 3: job3(); break;
  }
  /* Only master thread does this */
  if (tid == 0)
  {
   nthreads = omp_get_num_threads();
   printf("Number of threads = %d\n", nthreads);
  }
  for(;;) // master thread verteilt die aufgaben
  {
#pragma critical
   showAction=rand();
   usleep(100000); // nominell 100 ms
  }
 }  /* All threads join master thread and terminate */
}

Synchronisation

Mit den Pragmas von OpenMP kann man eine Synchronisation erreichen. Ein Thread wartet auf andere Threads, ich würde denken aktiv. Für Zwecke des Datensampelns sind die meisten Threads fast immer in Wartestellung. OpenMP bietet die Möglichkeit, Locks zu setzen. Darauf aufbauend könnte man eine sinnvolle Datenübergabe bauen und dazwischen die Threads Schlafen legen. Das stelle ich mir so vor: