Threads in C

Status
Not open for further replies.

zet0

New Member
22 Jul 2016
16
2
#1
Ich bereite mich gerade auf meine Klausur im Fach Hardwarenahe Programmierung vor. Bei einer Aufgabe habe ich allerdings das Problem dass ich sie entweder nicht richtig verstehe, oder sie nicht richtig Programmieren kann.
Vielleicht kann mir ja hier jemand helfen.
Aufgabe:
Schreiben Sie ein Programm,welches mittels 2 Threads arbeitet.
- Die beiden Threads sollen abwechselnd +1 auf die Variable Increment addieren
- die main() Funktion soll beendet werden wenn Increment 2000 erreicht hat
- Increment startet bei einem Wert von -1000

Meine Lösung :
Code:
#include <stdio.h>
#include <pthread.h>
 
long int Increment = -1000;
pthread_t p1, p2;
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
 
void *doit(void *);
 
void *doit(void *vptr){
 
    pthread_mutex_lock(&counter_mutex);
    printf("Thread %u : %ld\n",(unsigned int)pthread_self(),Increment);
    Increment+= 1;
    pthread_mutex_unlock(&counter_mutex);
}
 
 
int main(){
    do{
      pthread_create (&p1, NULL, doit, NULL);
      pthread_create (&p2, NULL, doit, NULL);
      pthread_join(p1, NULL);
      pthread_join(p2, NULL);
    }while(Increment <2000);
    if(Increment == 2000){
        printf("Thread %u : %ld\n",(unsigned int)pthread_self(),Increment);      
        return(0);
    }    
    printf("\n");
    printf("\nIst das main Programm schneller als die Threads?!\n");
}

Ein teil der Ausgabe:
Code:
Thread 2911819520 : 1990
Thread 2920212224 : 1991
Thread 2920212224 : 1992
Thread 2911819520 : 1993
Thread 2911819520 : 1994
Thread 2920212224 : 1995
Thread 2920212224 : 1996
Thread 2911819520 : 1997
Thread 2911819520 : 1998
Thread 2920212224 : 1999
Thread 2928531200 : 2000

Meine Fragen:
Habe ich die Aufgabe richtig verstanden, sodass "Cpu 0" +1 addieren soll danach "Cpu 1" +1 addieren soll und dann immer abwechselnd weiter bis Increment von 2000 erreicht ist.
Warum habe ich bei der Zahl 2000 aufeinmal einen neuen Thread der vorher nicht genutz wurde.
 
Last edited:

Sephirot

Well-Known Member
2 Jun 2015
1,751
1,265
#2
Hab mich mit solchen Thread wie du sie verwendest noch nie beschäftigt, würde aber mal sagen, das die letzte Thread Id anders ist, da du dies ausführst :

"if(Increment == 2000){
printf("Thread %u : %ld\n",(unsigned int)pthread_self(),Increment);
return(0);
} "
Schätze mal pthread_self gibt die ID von dem Thread an, in der die main liegt.
 
Likes: zet0

zet0

New Member
22 Jul 2016
16
2
#3
Danke für deine Hilfe, ich habe es lediglich unten noch einmal aufgerufen da mein Programm sonst bei 1999 endet.
Mache ich aus
Code:
if(Increment == 2000)     -----> if(Increment == 2001) und lösche die Befehle
"if(Increment == 2000){
printf("Thread %u : %ld\n",(unsigned int)pthread_self(),Increment);
return(0);
} "
ist die letzte Ausgabe 2001.

Habe meinen Code nochmals geändert und bekomme jetzt manchmal die Richtige Lösung manchmal nicht, je nachdem ob das main Programm schließt bevor der 2te Thread in die letzte Schleife geht.

Code:
#include <stdio.h>
#include <pthread.h>


long int Increment = -1000;
pthread_t p1, p2;
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;

void *doit(void *);

void *doit(void *vptr){

    pthread_mutex_lock(&counter_mutex);
    if(Increment < 2001){
    printf("Thread %u : %ld\n",(unsigned int)pthread_self(),Increment);
    }
    Increment += 1;
    pthread_mutex_unlock(&counter_mutex);
}


int main(){
    do{
      pthread_create (&p1, NULL, doit, NULL);
      pthread_create (&p2, NULL, doit, NULL);
      if(Increment == 2000){
        Increment = 2000;
        exit(0);
      }
      pthread_join(p1, NULL);
      pthread_join(p2, NULL);
    }while(Increment <2001);
}
https://imgur.com/RapDfEj
 
Last edited:

zet0

New Member
22 Jul 2016
16
2
#5
Ich würde es gerne anders lösen nur das haben wir leider nicht gelernt und im Internet finde ich keinen Ansatz dafür.
Das Problem ist das wir bisher eine Variable mit 2 Threads hochzählen lassen haben aber nicht so wie in der Aufgabenstellung gefordert.
Sondern nur nacheinander oder gemischt was ich nicht kontrollieren kann.
Code:
#include <stdio.h>
#include <pthread.h>

#define NLOOP 100
long int Counter = 0;
pthread_t p1, p2;
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;

void *doit(void *);

void *doit(void *vptr){

  int i;

  for(i=0;i<NLOOP;i++){

 
  Counter++;

  printf("Thread %u : %ld\n",(unsigned int)pthread_self(),Counter);

 
  }
  return NULL;
}







int main(int argc,char **argv){

  pthread_create (&p1, NULL, doit, NULL);
  pthread_create (&p2, NULL, doit, NULL);

  pthread_join(p1, NULL);
  pthread_join(p2, NULL);


  printf("\n");
  printf("\nIst das main Programm schneller als die Threads?!\n");

  return(0);
}
 
C

calb

Guest
#6
Ich würde es gerne anders lösen nur das haben wir leider nicht gelernt und im Internet finde ich keinen Ansatz dafür.
Das Problem ist das wir bisher eine Variable mit 2 Threads hochzählen lassen haben aber nicht so wie in der Aufgabenstellung gefordert.
Sondern nur nacheinander oder gemischt was ich nicht kontrollieren kann.
Code:
#include <stdio.h>
#include <pthread.h>

#define NLOOP 100
long int Counter = 0;
pthread_t p1, p2;
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;

void *doit(void *);

void *doit(void *vptr){

  int i;

  for(i=0;i<NLOOP;i++){

 
  Counter++;

  printf("Thread %u : %ld\n",(unsigned int)pthread_self(),Counter);

 
  }
  return NULL;
}







int main(int argc,char **argv){

  pthread_create (&p1, NULL, doit, NULL);
  pthread_create (&p2, NULL, doit, NULL);

  pthread_join(p1, NULL);
  pthread_join(p2, NULL);


  printf("\n");
  printf("\nIst das main Programm schneller als die Threads?!\n");

  return(0);
}

Gude,

erstell deine beiden Threads in main, dann lässt du in main eine While-Schleife laufen, welche prüft ob dein Integer den Wert 2000 angenommen hat, wenn dies der Fall ist beendest du beide Threads und benutzt ein "break" um die Schleife zu verlassen, danach gibst du deine 0 zurück und du bist fertig. :smile:

Grüße, calb.
 
Likes: zet0

zet0

New Member
22 Jul 2016
16
2
#7
Ich denke, das ich dann aber damit nicht die Aufgabe erfüllt habe "Die beiden Threads sollen abwechselnd +1 auf die Variable Increment addieren".
Oder ich habe deine Aussage nicht richtig Verstanden
 
C

calb

Guest
#8
Ich denke, das ich dann aber damit nicht die Aufgabe erfüllt habe "Die beiden Threads sollen abwechselnd +1 auf die Variable Increment addieren".
Oder ich habe deine Aussage nicht richtig Verstanden
Doch, du hast damit die Aufgabe erfüllt da dein Threads abwechseln den mutex locken/ freigeben und so dein Integer erhöhen. Wenn dir das nicht reicht kannst du ja mit bitflags arbeiten und diese setzen lassen von dem jeweiligen Thread. Kannst sehr kreativ sein! ^^

Grüße, calb.
 
Likes: zet0

zet0

New Member
22 Jul 2016
16
2
#9
Ich habe es jetzt so gemacht wie du es Vorgeschlagen hast. Jedoch bekomme ich beim mehrfachen ausführen nicht die gleichen Ausgaben.
Code:
#include <stdio.h>
#include <pthread.h>


long int Increment = -1000;
pthread_t p1, p2;
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;

void *doit(void *);

void *doit(void *vptr){
    pthread_mutex_lock(&counter_mutex);
    printf("Thread %u : %ld\n",(unsigned int)pthread_self(),Increment);
    Increment += 1;
    pthread_mutex_unlock(&counter_mutex);
}

int main(void){
    while(1){
      pthread_create (&p1, NULL, doit, NULL);
      pthread_create (&p2, NULL, doit, NULL);
      if(Increment == 2000){
        break;
      }
      pthread_join(p1, NULL);
      pthread_join(p2, NULL);
    }
}

https://imgur.com/a/rVirJ
 

Sephirot

Well-Known Member
2 Jun 2015
1,751
1,265
#10
while(1){
pthread_create (&p1, NULL, doit, NULL);
pthread_create (&p2, NULL, doit, NULL);
if(Increment == 2000){
break;
}

Es werden immer wieder neue Threads erstellt oder nicht?

Dies sollst du nicht in der Schleife laufen lassen.
 

zet0

New Member
22 Jul 2016
16
2
#11
Falls ich ihn nur einmal erstelle addiert jeder Thread auch nur 1 mal +1 und ich komme nicht auf Increment 2000.
Ich sitzte schon den ganzen Tag an der Aufgabe und habe schon einiges Probiert. Ich müsste dann eine for Schleife in die doit bauen die nur 1 mal durchläuft . Dann soll Thread Nr. 2 diese Schleife durchlaufen und danach wieder Thread Nr. 1 und so weiter . Dies habe ich leider nicht Programmiert bekommen.
 
C

calb

Guest
#12
Falls ich ihn nur einmal erstelle addiert jeder Thread auch nur 1 mal +1 und ich komme nicht auf Increment 2000.
Ich sitzte schon den ganzen Tag an der Aufgabe und habe schon einiges Probiert. Ich müsste dann eine for Schleife in die doit bauen die nur 1 mal durchläuft . Dann soll Thread Nr. 2 diese Schleife durchlaufen und danach wieder Thread Nr. 1 und so weiter . Dies habe ich leider nicht Programmiert bekommen.
Überleg mal wieso der Thread den Integer nur einmal erhöht.

Mal überlegt eine Schleife im Thread zu benutzen?
Code:
while( variable <= 2000 )

Wenn du willst können wir uns gleich mal zusammensetzen und ich gehe mit dir gemeinsam an dein Problem ran und erkläre dir Alles. ^^

Grüße, calb.
 

zet0

New Member
22 Jul 2016
16
2
#13
Das ist klar warum er das nur 1 mal macht.
Ich habe nur für mich keine andere Lösung gefunden. Falls du gleich Zeit hast können wir uns gerne mal auf einem Ts treffen.
 
C

calb

Guest
#14
Das ist klar warum er das nur 1 mal macht.
Ich habe nur für mich keine andere Lösung gefunden. Falls du gleich Zeit hast können wir uns gerne mal auf einem Ts treffen.
Wäre 20:15 auf dem ev0lve Teamspeak in Ordnung? :smile:

Grüße, calb.
 
Status
Not open for further replies.