2016-04-11 22 views
0

Ich habe den folgenden Code auf Ubuntu 14.04 und CentOS 7 mit GCC-Compiler ausgeführt, aber das seltsame ist, dass es unterschiedliche Ausgabe für die gleichen Eingänge zeigt. Es gibt zwei Probleme, die ich nicht lösen kann.Seltsame Multi-Threading-Ausgabe für verschiedene Plattformen

  1. Ich bekomme immer 0 in Summe (in Hauptfunktion) für die erste Multiplikation (1 * 1).
  2. Völlig unerwartete Ausgabe für Ubuntu. Hier ist der Code und beide Ausgänge.

-Code

#include<stdio.h> 
#include<pthread.h> 
#include<stdlib.h> 
#define N 15 
struct matrix 
{ 
    int num1, num2; 
}; 
void* multiply(void *c); 
int main() 
{ 
    int i, j, rows, cols, a[N][N], b[N][N], sum, k, final, res[N][N],*ptr; 
    pthread_t t1, t2; 
    struct matrix m1; 
    ptr=&sum; 
    printf("Enter the number of rows: "); 
    scanf("%d", &rows); 
    printf("Enter the number of cols: "); 
    scanf("%d", &cols); 
    for(i = 0; i < rows; i++) 
    { 
     for(j = 0; j < cols; j++) 
     { 
      printf("Enter the value at: a[%d][%d] : ", i, j);   
      scanf("%d", &a[i][j]); 
     } 
    } 
    for(i = 0; i < rows; i++) 
    { 
     for(j = 0; j < cols; j++) 
     { 
      printf("Enter the value at: b[%d][%d] : ", i, j);   
      scanf("%d", &b[i][j]); 
     } 
    } 
    for(i = 0; i < rows; i++) 
    { 
     for(j = 0; j < cols; j++) 
     { 
      final = 0; 
      for(k = 0; k < rows; k++) 
      { 
       m1.num1 = a[i][k]; 
       m1.num2 = b[k][j]; 
       pthread_create(&t1, NULL, (void*)multiply,(void*)&m1); 
       pthread_join(t1, (void**)&ptr); 
       sum=*ptr; 
       printf("\t%d",sum); 
       final += sum; 
       res[i][j] = final; 
      } 
      printf("\n"); 
     } 
    } 
    printf("The result is :\n"); 
    for(i = 0; i < rows; i++) 
    { 
     for(j = 0; j < cols; j++) 
     { 
      printf("%d\t", res[i][j]); 
     } 
     printf("\n"); 
    } 
    return 0; 
} 
void* multiply(void *c) 
{ 
    struct matrix *m; 
    m = (struct matrix *)c; 
    int p = 0; 
    p = m->num1 * m->num2; 
    printf("\t%d * %d = %d",m->num1,m->num2,p); 
    pthread_exit((void*)&p); 
} 

Ausgang für die Ausführung auf Ubuntu

Enter the number of rows: 2 
Enter the number of cols: 2 
Enter the value at: a[0][0] : 1 
Enter the value at: a[0][1] : 2 
Enter the value at: a[1][0] : 3 
Enter the value at: a[1][1] : 4 
Enter the value at: b[0][0] : 1 
Enter the value at: b[0][1] : 2 
Enter the value at: b[1][0] : 3 
Enter the value at: b[1][1] : 4 
    1 * 1 = 1 0 2 * 3 = 6 32648 
    1 * 2 = 2 32648 2 * 4 = 8 32648 
    3 * 1 = 3 32648 4 * 3 = 12 32648 
    3 * 2 = 6 32648 4 * 4 = 16 32648 
The result is : 
32648 65296 
65296 65296 

Ausgang für die Ausführung auf CentOS

Enter the number of rows: 2 
Enter the number of cols: 2 
Enter the value at: a[0][0] : 1 
Enter the value at: a[0][1] : 2 
Enter the value at: a[1][0] : 3 
Enter the value at: a[1][1] : 4 
Enter the value at: b[0][0] : 1 
Enter the value at: b[0][1] : 2 
Enter the value at: b[1][0] : 3 
Enter the value at: b[1][1] : 4 
    1 * 1 = 1 0 2 * 3 = 6 6 
    1 * 2 = 2 2 2 * 4 = 8 8 
    3 * 1 = 3 2 4 * 3 = 12 4 
    3 * 2 = 6 3 4 * 4 = 16 16 
The result is : 
6 10 
15 22 

Antwort

1

Die multiply Funktion einen Zeiger auf eine lokale Variable kehrt p, und die Lebensdauer der lokalen Variablen beendet, sobald die Funktion beendet.

Die einfachste Lösung ist hier nicht den Rückgabewert zu verwenden, aber einen Platz für das Ergebnis in den struct matrix zu reservieren, den multiply() übergeben wird, weil diese Struktur innerhalb main zugeordnet ist. Ändern Sie die Definition von struct multiply:

struct matrix 
{ 
    int num1, num2; 
    int product; 
}; 

ändern multiply() das Ergebnis setzen hier:

void *multiply(void *c) 
{ 
    struct matrix *m = c; 

    m->product = m->num1 * m->num2; 
    printf("\t%d * %d = %d", m->num1, m->num2, m->product); 
    return NULL; 
} 

ändern main(), um das Ergebnis abrufen von dort:

pthread_create(&t1, NULL, multiply, &m1); 
pthread_join(t1, NULL); 
sum = m1.product; 

(Randbemerkung: die Variable sum hat einen verwirrenden Namen, da er keine Summe enthält!)

+0

Aber die Handbuchseite von pthread_join sagt, dass es den Wert, der von Pthread_exit() zurückgegeben wird, auf die Ganzzahl setzt, auf die ptr (ptr in meinem Programm) zeigt. In diesem Sinne sollte ich nicht einfach den Wert von p in Summe erhalten, wenn ich ptr = & sum am Anfang deklariere? Ich habe es versucht, aber es hat nicht funktioniert. [hier] (http://man7.org/linux/man-pages/man3/pthread_join.3.html) ist der Link zu dieser Handbuchseite. –

+1

Der Exit-Status, der von Ihrem Thread zurückgegeben wird, ist nicht der Integer-Zeiger auf: es ist der Zeiger selbst (ein Zeiger auf die Variable "p" in "multiply()"). Dieser Pointer-Wert wird glücklicherweise von 'pthread_join()' in 'ptr' zurückgegeben, aber es ist nicht mehr gültig, da die angegebene Variable 'p' nicht mehr existiert. (Der Wert *, den der Zielthread an "pthread_exit()' * "in der Manpage angegeben hat, ist ein * Zeiger * -Wert). – caf

+0

Außerdem wird 'ptr' von' pthread_join() 'überschrieben, so dass es egal ist, was Sie am Anfang einstellen. Es zeigt auf "p", aber "p" ist nicht mehr da. – caf

Verwandte Themen