Frage

Neu bei der PThread -Programmierung und bei der Arbeit an einem C ++ & C gemischten Code an diesem Fehler festgehalten.

Was ich getan habe, ist, den C -Code im Thread aufzurufen, der vom C ++ - Code erstellt wurde. Es gibt einen statischen booleschen Zeiger is_center Wird im Thread verwendet und sollte beim Abschluss des Fadens frei werden.

Ich bemerkte jedoch, dass jedes Mal, wenn das Programm in die C -Funktion verarbeitet wurde, der Wert des Booleschen Zeigers geändert und der Segmentierungsfehler aufgrund des Free () geschah. Und das Problem tritt nur dann auf, wenn der C -Code verwendet wird. Entfernen Sie den C-Code und das Multi-Thread-C ++-Teil funktioniert gut.

Der Detailcode ist wie folgt:

static bool *is_center;

// omit other codes in between ...

void streamCluster( PStream* stream)
{
    // some code here ...
    while(1){
        // some code here ...
        is_center = (bool*)calloc(points.num,sizeof(bool));

        // start the parallel thread here.
        // the c code is invoked in this function.
        localSearch(&points,kmin, kmax,&kfinal); // parallel

        free(is_center);
    }

Und die Funktion mit Parallele lautet wie folgt (mein C -Code wird in jedem Thread aufgerufen):

void localSearch( Points* points, long kmin, long kmax, long* kfinal ) {
    pthread_barrier_t barrier;
    pthread_t* threads = new pthread_t[nproc];
    pkmedian_arg_t* arg = new pkmedian_arg_t[nproc];

    pthread_barrier_init(&barrier,NULL,nproc);

    for( int i = 0; i < nproc; i++ ) {
            arg[i].points = points;
            arg[i].kmin = kmin;
            arg[i].kmax = kmax;
            arg[i].pid = i;
            arg[i].kfinal = kfinal;
            arg[i].barrier = &barrier;

            pthread_create(threads+i,NULL,localSearchSub,(void*)&arg[i]);
    }

    for ( int i = 0; i < nproc; i++) {
        pthread_join(threads[i],NULL);
    }

    delete[] threads;
    delete[] arg;
    pthread_barrier_destroy(&barrier);
}

Endlich die Funktion, die meinen C -Code aufruft:

void* localSearchSub(void* arg_) {                                                                                                                                                        

    int eventSet = PAPI_NULL;                                                                                                                                                                                                                                                                                                                                     
    begin_papi_thread(&eventSet);                                                                                                                                                         

    pkmedian_arg_t* arg= (pkmedian_arg_t*)arg_;                                                                                                                                             
    pkmedian(arg->points,arg->kmin,arg->kmax,arg->kfinal,arg->pid,arg->barrier);                                                                                                            

    end_papi_thread(&eventSet);                                                                                                                                                                                                                                                                                                                                                 

    return NULL;                                                                                                                                                                            
}   

Und von GDB, was ich für die habe is_center ist:

Breakpoint 2, localSearchSub (arg_=0x600000000000bc40) at streamcluster.cpp:1711
1711      end_papi_thread(&eventSet);
(gdb) s

Hardware watchpoint 1: is_center

Old value = (bool *) 0x600000000000bba0
New value = (bool *) 0xa93f3
0x400000000000d8d1 in localSearchSub (arg_=0x600000000000bc40) at streamcluster.cpp:1711
1711      end_papi_thread(&eventSet);

Irgendwelche Vorschläge? Danke im Voraus!

Einige neue Informationen zum Code: Für den C -Code verwende ich das Papi -Paket. Ich schreibe meinen eigenen Papi -Wrapper, um Systemzähler zu initialisieren und zu lesen. Der Code ist wie folgt:

void begin_papi_thread(int* eventSet)                                                                                                                                                     
{                                                                                                                                                                                         
    int thread_id = pthread_self();                                                                                                                                                       
    // Events                                                                                                                                                                             
    if (PAPI_create_eventset(eventSet)) {                                                                                                                                                 
        PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);                                                                                                                        
        printf("*** ERROR *** Failed to create event set for thread %d: %s\n.", thread_id, error_string);                                                                                 
    }                                                                                                                                                                                     
    if((return_value = PAPI_add_events(*eventSet, event_code, event_num)) != PAPI_OK)                                                                                                     
    {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
        printf("*** ERROR *** Failed to add event for thread %d: %d.\n", thread_id, return_value);                                                                                                                                                                                                                                                                         
    }                                                                                                                                                                                     
    // Start counting                                                                                                                                                                     
    if ((return_value = PAPI_start(*eventSet)) != PAPI_OK) {                                                                                                                                                                                                                                                                                                              
        PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);                                                                                                                                                                                                                                                                                                         
        printf("*** ERROR *** PAPI failed to start the event for thread %d: %s.\n", thread_id, error_string);
    }                                                                                                                                                                                                                                                                                                                                                                             
}  
void end_papi_thread(int* eventSet)                                                                                                                                                       
{                                                                                                                                                                                         
    int thread_id = pthread_self();                                                                                                                                                       
    int i;                                                                                                                                                                                

    long long * count_values = (long long*)malloc(sizeof(long long) * event_num);                                                                                                         
    if (PAPI_read(*eventSet, count_values) != PAPI_OK)                                                                                                                                    
        printf("*** ERROR *** Failed to load count values.\n");                                                                                                                           

    if (PAPI_stop(*eventSet, &dummy_values) != PAPI_OK) {
        PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);
        printf("*** ERROR *** PAPI failed to stop the event for thread %d: %s.\n", thread_id, error_string);
        return;
    }
    if(PAPI_cleanup_eventset(*eventSet) != PAPI_OK)
        printf("*** ERROR *** Clean up failed for the thread %d.\n", thread_id);                                                                                                          
} 
War es hilfreich?

Lösung

Ich glaube nicht, dass Sie genug Code gepostet haben, um Ihr Problem wirklich zu verstehen, aber es sieht misstrauisch aus, dass Sie deklariert haben is_center global. Ich gehe davon aus, dass Sie es an mehr als einem Ort verwenden, möglicherweise an mehreren Threads (localSearchSub erwähnt es, was Ihre Worker -Thread -Funktion ist).

Wenn is_center Wird von mehreren Threads gelesen oder geschrieben, möchten Sie es wahrscheinlich mit einem schützen pthread mutex. Sie sagen, es ist "befreit, wenn der Thread fertig ist", aber Sie sollten sich bewusst sein, dass es gibt nprocs Themen, und es sieht so aus, als würden sie alle an einer Reihe von einer Reihe von arbeiten is_center[points] Bools. Wenn points != nproc, das könnte schlimm [1]. Jeder Thread sollte wahrscheinlich in seinem eigenen Array funktionieren, und localSearch sollte die Ergebnisse aggregieren.

Das xxx_papi_thread Funktionen erhalten keine Treffer bei Google, daher kann ich mir nur vorstellen, dass es Ihr eigenes ist ... unwahrscheinlich können wir Ihnen helfen, wenn das Problem dort ist :)

1]: auch wenn points == nproc, Es ist nicht unbedingt in Ordnung, aus mehreren Threads an verschiedene Elemente eines Arrays zu schreiben (es ist Compiler und Prozessor abhängig). Seien Sie sicher, verwenden Sie einen Mutex.

Außerdem ist dies mit dem Tag gekennzeichnet C++. Können Sie das ersetzen? calloc und dynamische Arrays (verwenden new) mit vectors? Es könnte einfacher zu debuggen, und es ist sicherlich einfacher zu pflegen. Warum hassen und möchten Sie die Leser Ihres Codes bestrafen? ;))

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top