0

スレッドを作成しました。主な機能は、要素を作成し、それをキューの Tail/End に追加することです。スレッドは Head/Start からリストを読み取り、その後メモリを解放しています。

次のコードがあります。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *print_message_function( void *ptr );

typedef struct stCheckFree
{
    char name[30];
    int doneflag;
    struct stCheckFree *next;
}CheckFree;

CheckFree *gHead=NULL;
CheckFree *gTail=NULL;

int main()
{
    pthread_t thread1;
    char *message1 = "Thread 1";
    int iret1;
    unsigned long TestCount=1;

    CheckFree *pCurr=NULL;
    CheckFree *pTemp=NULL;

    iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);

    while(1)
    {
        pCurr=malloc(sizeof(CheckFree));
        memset(pCurr,0,sizeof(CheckFree));

        printf("Malloc\n");
        sprintf(pCurr->name,"Test-%ld",TestCount); TestCount++;
        pCurr->doneflag=0;
        pCurr->next=NULL;

        pTemp=gTail;
        gTail=pCurr;
        if(pTemp) pTemp->next=gTail;

        if(!gHead)
        {
            gHead=gTail;
        }

    }

    return 0;
}

void *print_message_function( void *ptr )
{
    CheckFree *pTrav;

    while(1)
    {
        pTrav=gHead;
        if(pTrav)
        {
            printf("[%s]\n",pTrav->name);
            pTrav->doneflag=1;

            gHead=gHead->next;
            free(pTrav);
        }
    }
}

コードを実行すると、segfault が発生します。問題は何ですか?助けてください!

ありがとう。

PS- free() を削除すると、見事に実行されます!!!

-------------------------------------------------- ---------------------
---編集1
------ --------- -------------------------------------------------- ------------------------

これで問題が解決したかどうかはわかりませんが、他のスタックオーバーフローメンバーからの入力がさらに必要です。

void *print_message_function( void *ptr )
{
    CheckFree *pTrav;

    while(1)
    {
        pTrav=gHead;
        if(pTrav)
        {
            printf("[%s]\n",pTrav->name);
            pTrav->doneflag=1;

            gHead=gHead->next;

            if(!gHead) gTail=NULL;                /* NEW CODE */

            free(pTrav);
            sleep(0.7);
        }
    }
}

大事なことだから助けて!:) 再度、感謝します。

-------------------------------------------------- ---------------------
--- 編集 2 ---
------ --------- -------------------------------------------------- ------------------------

コードの変更:- if(!gHead) gTail=NULL; /* NEW CODE */ は、NULL を再初期化することによってデータを破壊しています。

次のコード変更を行うだけで確認できます。

...
pTemp=gTail;
gTail=pCurr;
if(pTemp) pTemp->next=gTail;
if(!gTail)printf("データが失われました\n");
if(!gHead)
{
...

この問題を修正するのを手伝ってください...

-------------------------------------------------- ---------------------------------
--- 編集 3 ---
------ --------- -------------------------------------------------- ------------------------
相互排他ロックを使用するという @wazy の推奨に従い、コードを次のように更新しました:-

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void * thread_function( void *ptr );

typedef struct stCheckFree
{
    char name[30];
    int doneflag;
    struct stCheckFree *next;
}CheckFree;

pthread_mutex_t lock;    // EDIT 3

CheckFree *gHead=NULL;
CheckFree *gTail=NULL;

int main()
{
    pthread_t thread1;
    char *message1 = "Thread 1";
    int  iret1;
    unsigned long TestCount=1;

    CheckFree *pCurr=NULL;
    CheckFree *pTemp=NULL;

    if (pthread_mutex_init(&lock, NULL) != 0)    // EDIT 3
    {
        printf("\n mutex init failed\n");
        return 1;
    }

    iret1 = pthread_create( &thread1, NULL,  thread_function, (void*) message1);

    while(1)
    {
        pCurr=malloc(sizeof(CheckFree));
        memset(pCurr,0,sizeof(CheckFree));

        sprintf(pCurr->name,"Test-%ld",TestCount); TestCount++;
        pCurr->doneflag=0;
        pCurr->next=NULL;

        pTemp=gTail;
        gTail=pCurr;
        if(pTemp) pTemp->next=gTail;


        //pthread_mutex_lock(&lock);    // EDIT 3(commented out)
        if(!gHead)
        {
            pthread_mutex_lock(&lock);    // EDIT 4
            gHead=gTail;
            pthread_mutex_unlock(&lock);    // EDIT 4
        }
        //pthread_mutex_unlock(&lock);    // EDIT 3(commented out)
    }

    pthread_join( thread1, NULL);
    printf("Thread 1 returns: %d\n",iret1);

    return 0;
}

void * thread_function( void *ptr )
{
    CheckFree *pTrav;

    while(1)
    {
        pTrav=gHead;
        if(pTrav)
        {
            //printf("[%s]\n",pTrav->name);
            pTrav->doneflag=1;

            gHead=gHead->next;
            if(!gHead) sleep(1);//gTail=NULL;
            free(pTrav);
        }
    }
}

私は正しい軌道に乗っていますか????? ありがとう!!!

4

1 に答える 1

1

コードを実行すると、glibc から二重解放または破損 (fasttop) が発生します。コードを見ると、thread1 とメイン スレッドの両方で gHead を使用していることがわかります。マルチスレッド同期の問題のようです。

于 2013-03-02T20:08:08.197 に答える