Forum: PC-Programmierung Pthread - Strange Problem


von Michael H. (overthere)


Lesenswert?

Hallo,

ich habe ein Super-Strange-Problem mit Ptreads. (Muss aber dazu sagen, 
ich habe damit keine Erfahrungen). Ich habe ein Dual-Core-Prozessor und 
habe ein Optimierungsprogramm geschrieben. Das Programm macht nichts 
weiter als ein bissel Speicher anfordern und etwas rechnen.
Das ganze Programm ist so strukturiert, dass es 2 "Rechenesel" gibt, 
diese sind vollkommen gleich aufgebaut, bisauf dass sie etwas vorschoben 
arbeiten. Lasse ich die Dinger hintereinander laufen, gibt es keine 
Probleme, lasse ich die Threads gemeinsam laufen gibt es irgendwelche 
Segmentation-Faults. Aber erst nach wenigen Sekunden...
1
// Das hier sind globale Variablen
2
  GList* global_list1=NULL;
3
  GList* global_list2=NULL;
4
  rp_t*  global_regelparameter1=NULL;
5
  rp_t*  global_regelparameter2=NULL;
6
7
8
void *optimisation_thread1(void* arg){
9
  printf("Thread1 started\n");
10
  rp_t* regelparameter1=global_regelparameter1;
11
  double ianteil, danteil;
12
  GList* listopti1=NULL;
13
  pwm_t* pwmval1=init_pwm_struct();  
14
  int target1=adc_convert(regelparameter1,0.7);
15
  for(ianteil=0;ianteil<2;ianteil=ianteil+0.02){
16
    for(danteil=0;danteil<2;danteil=danteil+0.01){
17
      bewfac_t* bf=optimisation_init1(ianteil,danteil,target1);
18
      reset_pwm_val(pwmval1);
19
      optimisation_simulate(regelparameter1,pwmval1,bf);
20
      //optimisation_print_error(bf);
21
      listopti1=g_list_prepend (listopti1,bf);
22
      //optimisation_print_error(bf);
23
    }
24
  }
25
  printf("Task1finished\n");
26
  global_list1=listopti1;
27
  return 0;
28
}
29
void *optimisation_thread2(void* arg){
30
  printf("Thread2 started\n");
31
  rp_t* regelparameter2=global_regelparameter2;
32
  double ianteil, danteil;
33
  GList* listopti2=NULL;
34
  pwm_t* pwmval2=init_pwm_struct();
35
  int target2=adc_convert(regelparameter2,0.7);
36
  for(ianteil=0.01;ianteil<2;ianteil=ianteil+0.02){
37
    for(danteil=0;danteil<2;danteil=danteil+0.01){
38
      bewfac_t* bf=optimisation_init2(ianteil,danteil,target2);
39
      reset_pwm_val(pwmval2);
40
      optimisation_simulate(regelparameter2,pwmval2,bf);
41
      //optimisation_print_error(bf);
42
      listopti2=g_list_prepend (listopti2,bf);
43
      //optimisation_print_error(bf);
44
    }
45
  }
46
  printf("Task2finished\n");
47
  global_list2=listopti2;
48
  return 0;
49
  
50
}
Habt ihr eine Idee, woran es liegen kann?

von Daniel -. (root)


Lesenswert?

init_pwm_struct()
adc_convert()
optimisation_simulate()...

nicht thread-safe?
irgendwo in ihnen finden static oder globale Zugriffe statt?

von Georg A. (Gast)


Lesenswert?

> irgendwelche Segmentation-Faults.

Soso, irgendwelche... Ich gehe mal soweit zu behaupten, dass ein 
Backtrace von irgendwelchen Segfaults in 90% aller Fälle bereits reicht, 
die Ursache zu erkennen bzw. sehr stark einzukreisen.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Zwei Möglichkeiten:
1. GDB verwenden um den Fehler zu finden
2. Thread-Gewurstel sein lassen, und stattdessen OpenMP verwenden.

von Michael H. (overthere)


Lesenswert?

Okay, gerade mal gdb angeschmissen. Scheinbar ist die GLib nicht 
thread-save, mein Sach jedenfalls ist es! (Danke für den Tipp mit dem 
Backtrace)
=======
[Thread debugging using libthread_db enabled]
[New Thread 0xb7d48b70 (LWP 1313)]
Thread1 started
[New Thread 0xb7548b70 (LWP 1314)]
Thread2 started

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7548b70 (LWP 1314)]
0xb7f1a599 in ?? () from /usr/lib/libglib-2.0.so.0
(gdb) backtrace
#0  0xb7f1a599 in ?? () from /usr/lib/libglib-2.0.so.0
#1  0xb7f1b583 in g_slice_alloc () from /usr/lib/libglib-2.0.so.0
#2  0xb7efafe6 in g_list_prepend () from /usr/lib/libglib-2.0.so.0
#3  0x08049ad5 in optimisation_thread2 ()
#4  0xb7eb3830 in start_thread () from /lib/libpthread.so.0
#5  0xb7e2a15e in clone () from /lib/libc.so.6
===
Konkret dürfte es dann an diesem scheitern:
listopti2=g_list_prepend (listopti2,bf);
Ich habe das jetzt mehrmals durchgefürt und es liegt immer daran. Da hat 
mich die G-Lib schwer enttäuscht. Ich frage mal direkt bei den 
G-Lib-Menschen nach. Wenn ihr ein paar Tipps für mich habt, nur raus 
damit...

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Michael H. schrieb:
> Da hat mich die G-Lib schwer enttäuscht
Goldene Regel: Wenn es nicht explizit dabeisteht ist eine Funktion nicht 
Threadsave, nur um weiteren Enttäuschungen vorzubeugen ;)

von Michael H. (overthere)


Lesenswert?

Ich habe jetzt OpenMP genommen, das funktioniert super. Vielen Dank für 
den Tipp... Jetzt fehlen nurnoch ein paar Prozessorkerne mehr, die man 
haben sollte... ;)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.