0

posixスレッドを処理しようとしている奇妙な問題をブロックしています。コードから始めましょう:

#include <pthread.h>
#include <semaphore.h>


typedef struct {
    pthread_mutex_t *mutex; 
} buffer_t;


buffer_t *buffer_alloc(unsigned int maxSize) {

    buffer_t *buffer = (buffer_t *) malloc(sizeof(buffer_t));
    if(buffer == NULL)
        return NULL;

    pthread_mutex_init(buffer->mutex, NULL); // This line causes a crash

    pthread_mutex_t *mutex;
    pthread_mutex_init(mutex, NULL); // This one doesn't

}

最初にセグメンテーション違反が発生しましたpthread_mutex_init()。gdbのrunlogとバックトレースは次のとおりです。

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".


Program received signal SIGSEGV, Segmentation fault.
__pthread_mutex_init (mutex=0x0, mutexattr=0x0) at pthread_mutex_init.c:83
83  pthread_mutex_init.c: No such file or directory.

(gdb) backtrace
#0  __pthread_mutex_init (mutex=0x0, mutexattr=0x0) at pthread_mutex_init.c:83
#1  0x00000000004015a8 in buffer_alloc (maxSize=10) at buffers.c:26

ご協力いただきありがとうございます !

4

3 に答える 3

4

構造体の定義を次のように変更します。

typedef struct {
    pthread_mutex_t mutex; 
} buffer_t;

次に、ミューテックスの初期化を次のように行います。

pthread_mutex_init(&buffer->mutex, NULL);

どちらの場合も、コードは初期化されていないポインタを使用しています。2番目のケースで(すぐに)セグメンテーション違反を引き起こさないのは幸運であり、おそらくいくつかの変数が破損し、後で問題が発生します。

于 2013-03-26T19:17:13.277 に答える
2

渡すポインタpthread_mutex_init()は初期化されておらず、割り当てられたメモリを指していないため、プログラムは未定義の動作を呼び出します。できることは、構造体またはbuffer_alloc()関数を変更して、ミューテックスにメモリを明示的に割り当てることです。つまり、ソリューション#1(私はこれが好きです):

typedef struct {
    pthread_mutex_t mutex;
} buffer_t;

buffer_t *buffer_alloc(unsigned int maxSize)
{
    buffer_t *buffer = malloc(sizeof(*buffer));
    if (buffer == NULL)
        return NULL;

    pthread_mutex_init(&buffer->mutex, NULL);

    // etc.
    return buffer;
}

ソリューション#1、動的割り当て:

typedef struct {
    pthread_mutex_t *mutex;
} buffer_t;

buffer_t *buffer_alloc(unsigned int maxSize)
{
    buffer_t *buffer = malloc(sizeof(*buffer));
    if (buffer == NULL)
        return NULL;

    buffer->mutex = malloc(sizeof(*(buffer->mutex)));
    if (buffer->mutex == NULL) {
        free(buffer);
        return NULL;
    }

    pthread_mutex_init(buffer->mutex, NULL);

    // etc.
    return buffer;
}

free()後者の場合、 「デストラクタ」でもミューテックスを忘れないでください。

また、の戻り値をキャストしないでくださいmalloc()

于 2013-03-26T19:19:02.557 に答える
0

初期化されていないバッファを渡しています....buffer_tを割り当てましたが、何も初期化していません。したがって、ミューテックスポインタは、誰がどこを知っているかを示すランダムな値です。

次に、pthread_mutex_initは、実際に存在するミューテックスへのポインターを予期します。あなたはそれにランダムメモリへのポインタを渡しています。

これで修正されないかどうかを確認してください...

typedef struct {
    pthread_mutex_t mutex; 
} buffer_t;


buffer_t *buffer_alloc(unsigned int maxSize) {

    buffer_t *buffer = (buffer_t *) malloc(sizeof(buffer_t));
    if(buffer == NULL)
        return NULL;

    pthread_mutex_init(&buffer->mutex, NULL); // This line causes a crash
于 2013-03-26T19:18:23.233 に答える