2010-04-28 6 views
2

Une erreur est survenue lors de l'insertion de i malloc pthread_t pour enregistrer un identifiant de thread nouvellement créé et le libérer dans un autre thread. Codes comme suit:Adresse d'erreur lorsque malloc/libre pthread_t sur les threads

typedef struct _TaskInfo { 
    // int dummy_int; 
    pthread_t tid; 
} TaskInfo; 

void* dummy_task(void* pArg) { 
    free(pArg); 
    return NULL; 
} 

void create_task() { 
    TaskInfo *pInfo; 
    pthread_attr_t attr; 

    // set detached state stuff ... 

    pInfo = (TaskInfo*) malloc(sizeof(TaskInfo)); 
    pthread_create(&pInfo->tid, &attr, dummy_task, pInfo); 

    // destroy pthread attribute stuff ... 
} 

int main() { 
    int i; 
    while(i < 10000) { 
     create_task(); 
     ++i; 
    } 
    return 0; 
} 

Quand je l'décommenter dummy_int membre de TaskInfo parfois couru avec succès, mais parfois échoué. Ma plate-forme est VMWare + Ubuntu 9.10 + ndk r3

Merci!

Répondre

1

pthread_create() stocke l'ID de fil (TID) du fil créé à l'emplacement pointé par le premier paramètre, mais il le fait après que le fil est créé (http://opengroup.org/onlinepubs/007908799/xsh/pthread_create.html):

Après avoir réussi, pthread_create() stocke l'ID du fil créé à l'emplacement référencé par fil

Depuis le fil a déjà été créé, il pourrait bien avoir la chance de courir et supprimer ce bloc de mémoire avant pthread_create() obtient une chance de stocker le TID dedans.

Lorsque vous n'avez pas le membre dummy_int dans la structure, vous endommagez probablement le segment de mémoire d'une manière qui se bloque plus tôt. Avec le membre dummy_int inclus, vous êtes en train d'éliminer quelque chose de moins sensible (donc les plantages sont un peu moins fréquents). Dans les deux cas, vous rayer de la mémoire qui n'est pas allouée (ou ne peut pas être allouée - vous avez une condition de concurrence).

+0

Merci beaucoup! Mais je me demande toujours pourquoi les mêmes codes sur Linux fonctionnent bien. Parce que j'ai lu dans le "Linux Kernel Development" de Robert Love que le noyau exécute d'abord le processus fils et que l'implémentation du processus et du thread sur Linux est la même. La planification des threads sur Linux diffère-t-elle d'Android? – scleung

+0

Je ne pourrais pas dire - mais dans les deux cas, puisque vous avez affaire à une condition de concurrence, vous avez affaire à du code qui va échouer à un moment donné. Il se peut que l'échec soit plus «certain» sur Android parce que vous avez probablement affaire à un seul processeur, alors que sous Linux, vous pouvez utiliser un périphérique multiproc pour que le thread d'origine ait la possibilité de sauvegarder le TID avant le 'free()' se produit dans le thread nouvellement créé. Ou Linux peut avoir assez de différence dans le planificateur pour vous permettre de le faire. Mais c'est toujours un bug - vous ne le remarquez pas dans certains cas. –

Questions connexes