Announcement

Collapse
No announcement yet.

[Linux Ubuntu "C-Sprache"] Semaphoren -> Prozesse

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • [Linux Ubuntu "C-Sprache"] Semaphoren -> Prozesse

    Hi,
    ich habe mich mal an ein Beispiel gesetzt, um die Semaphoren vielleicht besser zu verstehen, aber irgendwie klappt das nicht. Hab wahrscheinlich einen Denkfehler.

    Szenario war, dass man zwei Kassen hat und 10 Autos anstehen. Nun kommt ein Auto an Kasse 1 (Kasse 1 wird gesperrt) und das Auto danach an Kasse 2 (Kasse 2 wird gesperrt). Dann, wenn ein Auto fertig ist, wird die jeweilige Kasse wieder freigegeben.

    Nun mein - naja - Code

    Code:
    // HINWEIS !!! :
    // Kompilieren --> gcc -o _____ _____.c -lrt
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/wait.h>
    #include <signal.h>
    #include <semaphore.h>
    #include <fcntl.h>
    #include <sys/errno.h>
    #include <sys/types.h>
     
    int main(){
        sem_t* sema;
        sem_t* semb;
        pid_t i_pid[10];
        int i;
        int val1;
     
        sem_unlink("Kasse 1");
        sem_unlink("Kasse 2");
        sema = sem_open("Kasse 1", O_CREAT, 0700, 1);
        semb = sem_open("Kasse 2", O_CREAT, 0700, 1);
     
        for(i = 1; i <= 20; i++) {
            if((i_pid[i]= fork()) == 0){
                break;
            }
        }
    
        val1=sem_getvalue(sema, &val1);
    
        if(val1 == 1){
            sem_wait(sema);
            printf("[val1 = %d] Kasse1\n", val1);
            sem_post(sema);     
        }else{
            sem_wait(semb);           
            printf("[val1 = %d] Kasse2\n", val1);
            sem_post(semb);
        }
     
        waitpid(i_pid[19],0,0);
         
        for(i = 0; i<20; i++){
            kill(i_pid[i], 15);
        }
        
     
       sem_close(sema);
       sem_close(semb);
    
         
        printf("/*---------Prozesse-----------------*/\n");
        system("ps -e -u");
        printf("/*---------Ende: Prozesse-----------*/\n");
        return 0;
    }
    Bitte um Hilfe
    Zuletzt editiert von creator90; 12.06.2010, 17:12.
    PHP Code:
    <?php
    echo 'http://acs-it-worx.de/';
    echo 
    'http://www.youtube.com/user/ACSITWorx/'// mein YouTube Kanal
    echo '-----------------------------------------------------------------';
    echo 
    'http://www.autoservice-asberg.de/';
    ?>

  • #2
    hi,
    wieso arbeitest du mit fork()??

    warum machst du keine 10 Threads und übergibst denen eine Funktion z.B. "void * balance" diese überprüft dann die Kassen ob sie frei sind und gibt dementsprechend einen Thread entweder an Kasse 1 oder Kasse 2.

    lg, ssoul21

    Comment


    • #3
      Threads?
      meinst Du wie if(){}else{} ?

      Was ist so nachteiliges an fork()?
      PHP Code:
      <?php
      echo 'http://acs-it-worx.de/';
      echo 
      'http://www.youtube.com/user/ACSITWorx/'// mein YouTube Kanal
      echo '-----------------------------------------------------------------';
      echo 
      'http://www.autoservice-asberg.de/';
      ?>

      Comment


      • #4
        Hi,
        ne if und else oder while etc. sind alles Verzweigungen. Threads sind Vorgänge die parallel laufen. Bei deinem Fall wäre ein Auto ein Thread. Jedes Auto hat also einen Ablauf nämlich: Gehe an Kasse 1, falls dort besetzt dann zieh weiter zu Kasse 2 etc. Und das machen dann 10 Autos. Damit jetzt hier kein Chaos aufkommt benutzt man z.B. entweder Mutex oder Semaphoren, die -im günstigsten Fall- eine parallelität bewirken sollten.

        Bevor ich dir hier Fork() erkläre schau einfach mal hier rein: http://de.wikipedia.org/wiki/Fork_%28Unix%29

        Für Semaphoren und auch noch ein bisschen Fork() (alles auf Englisch) schaue hier: http://www.beej.us/guide/bgipc/outpu...age/bgipc.html

        Und das alles hier ist für Threads, find ich sehr informativ und einfach zu verstehen: https://computing.llnl.gov/tutorials/pthreads/

        Lg, ssoul21

        Comment


        • #5
          Thx, weerd ich mir mal anschauen.

          Wg. des Codes oben: Was hakt da?
          PHP Code:
          <?php
          echo 'http://acs-it-worx.de/';
          echo 
          'http://www.youtube.com/user/ACSITWorx/'// mein YouTube Kanal
          echo '-----------------------------------------------------------------';
          echo 
          'http://www.autoservice-asberg.de/';
          ?>

          Comment


          • #6
            Ich hab mich jetzt mal an die Threads gesetzt und mal was progrmmiert, aber ich glaube, dass ich immernoch zu fixiert bin auf die zwei Kassen:

            Code:
            // HINWEIS !!! :
            // Kompilieren --> gcc -o _____ _____.c -lpthread
            
            #include <stdlib.h>
            #include <stdio.h>
            #include <sys/wait.h>
            #include <signal.h>
            //#include <semaphore.h>
            #include <fcntl.h>
            #include <sys/errno.h>
            #include <sys/types.h>
            #include <unistd.h>
            #include <pthread.h>
            
            pthread_mutex_t mutex01;
            pthread_mutex_t mutex02;
            int i;
            
            void *Kasse1 (void *i)
            {
              pthread_mutex_lock (&mutex01);
              sleep (2);
              printf ("%d. Kasse 1\n", *(int *)i);
              pthread_mutex_unlock (&mutex01);
              return NULL;
            }
            
            void *Kasse2 (void *i)
            {
              pthread_mutex_lock (&mutex02);
              sleep (1);
              printf ("%d. Kasse 2\n", *(int *)i);
              pthread_mutex_unlock (&mutex02);
              return NULL;
            }
            
            int main ()
            {
              pthread_t p[10];
            
              pthread_mutex_init (&mutex01, NULL);
              pthread_mutex_init (&mutex02, NULL);
                
                for(i = 0; i < 10; i++){        
                    pthread_create (&p[i], NULL, Kasse2, (void *)&i);        
                    pthread_join (p[i], NULL);
                    pthread_create (&p[i], NULL, Kasse1, (void *)&i);
            
                }
              return 0;
            }
            Die Ausgabe stimmt aber wieder nicht!
            http://event4net.de/EntwicklerForum/...ds/threads.png

            (Die Miniaturansicht hier ist ein bisschen klein geworden, deshalb hab ich das Bild zusätzlich auf den Server "event4net.de" geladen)
            Attached Files
            Zuletzt editiert von creator90; 13.06.2010, 16:38.
            PHP Code:
            <?php
            echo 'http://acs-it-worx.de/';
            echo 
            'http://www.youtube.com/user/ACSITWorx/'// mein YouTube Kanal
            echo '-----------------------------------------------------------------';
            echo 
            'http://www.autoservice-asberg.de/';
            ?>

            Comment


            • #7
              Hi,
              na das sieht ja schon einmal viel viel besser aus

              Aber:
              for(i = 0; i < 10; i++){
              pthread_create (&p[i], NULL, Kasse2, (void *)&i);
              pthread_join (p[i], NULL);
              pthread_create (&p[i], NULL, Kasse1, (void *)&i);

              }
              Hier erzeugst du zwei gleichnamige Threads ist nicht sehr elegant und kann auch zu Fehlern führen, trenne auch die pthread_join von der "Creation-For-Schleife"

              So ist es üblich:
              for(i=0;i<10;i++)
              {
              pthread_create (&p[i],NULL, *[FUNKTION],(void*)*[VARIABLE]);
              }

              for(x=0;x<10;x++)
              {
              pthread_join (p[x],NULL);
              }
              Deine zwei Kassenmethoden haben keinen Rückgabewert und führen nur "simple" Anweisungen aus. Trenne dich komplett von Ihnen und setze Anweisungen z.B in eine IF-Schleife. Jede besetzte Kasse kannst du mit einer 0-1 Flag versehen (0-frei, 1-besetzt). Je nach Zustand wird dann eine freie Kasse angesteuert oder gewartet.

              Ich schreib dir gleich mal einen Code (bzw. verändere deinen) den ich dann einfügen werden.

              Lg,ssoul21

              So, nachträglich ein kleiner Code (geht natürlich besser und eleganter):
              #include <stdlib.h>
              #include <stdio.h>
              #include <sys/wait.h>
              #include <signal.h>
              #include <semaphore.h>
              #include <fcntl.h>
              #include <sys/errno.h>
              #include <sys/types.h>
              #include <unistd.h>
              #include <pthread.h>




              int i,x;
              int kasse1=0,kasse2=0;
              sem_t semaphore;
              pthread_mutex_t mutex;

              void *KassenHandler (void *i)
              {
              sem_wait(&semaphore);



              if(kasse1==0)
              {
              //printf("%d",kasse1);
              //printf ("%d. Entering Kasse 1\n", (int *)i);
              kasse1=1;
              sleep(1);
              //...Anweisungen
              printf ("%d. Kasse 1\n", (int *)i);
              kasse1=0;


              }else if(kasse2==0)
              {
              //printf("%d",kasse1);
              //printf ("%d. Entering Kasse 2\n", (int *)i);
              kasse2=1;
              sleep(1);

              //..Anweisungen
              printf ("%d. Kasse 2\n", (int *)i);
              kasse2=0;
              }

              sem_post(&semaphore);
              //pthread_exit(NULL);

              }



              int main ()
              {

              pthread_t p[10];
              sem_init(&semaphore,NULL,2);
              pthread_mutex_init(&mutex,NULL);


              for(i = 0; i < 10; i++){
              pthread_create (&p[i], NULL, KassenHandler, (void *)i);
              }

              for(x=0;x<10;x++)
              {
              pthread_join(p[x],NULL);
              }
              return 0;
              }
              Zuletzt editiert von ssoul21; 14.06.2010, 14:28.

              Comment


              • #8
                Wow. Danke. Werd ich mir dann mal anschauen
                PHP Code:
                <?php
                echo 'http://acs-it-worx.de/';
                echo 
                'http://www.youtube.com/user/ACSITWorx/'// mein YouTube Kanal
                echo '-----------------------------------------------------------------';
                echo 
                'http://www.autoservice-asberg.de/';
                ?>

                Comment

                Working...
                X