2013-04-26 73 views
7

これは私の最初のスレッドCでの試みです。私は循環的に制限されたバッファを作成しています。私はスレッドを作成する方法を知っているが、私は唯一の見てきたすべての例は、1つのボイドパラメータを受け入れる関数をスレッド化しているが、残念ながら私の労働者の仕様は、ここに示すように、3を使用するように私を必要とします。ここでは複数の引数をスレッド関数に渡すpthread_create

void bufferRead(BoundedBuffer* buffer, char* data, int count) { 
    pthread_mutex_lock(&buffer->mutexBuffer); 
    <snip> 
    pthread_mutex_unlock(&buffer->mutexBuffer); 
} 

は私のpthread_createです声明

pthread_create(&buffer.readThread, NULL, (void *)bufferRead, &readParams) 

そして、私のreadParams構造体/割り当て

struct readThreadParams {             
    BoundedBuffer b;               
    char* data;                
    int count;                
};                   

struct readThreadParams readParams;           
readParams.b = buffer2;              
readParams.data = out_array;             
readParams.count = in_size; 

Bに通過した後、構造体の各パラメータを割り当てる方法上の任意のアドバイスufferRead関数は非常に高く評価されます。

答えて

8

本当にが必要なのは、のパラメータが1つだけだからです。一般的にそうであるように、複数の値がある場合、それを構造体にカプセル化します。 pthread_createが呼び出す関数の型は、ネゴシエートできません。これは、関数ポインタを型キャストすることで深刻な問題になることがある領域です。

#include <pthread.h> 
#include <stdlib.h> 

struct BoundedBuffer { 
    pthread_t readThread; 
    pthread_mutex_t mutexBuffer; 
} buffer2; 

struct readThreadParams { 
    struct BoundedBuffer b; 
    char* data; 
    int count; 
}; 

void *bufferRead (void *context) { 
    struct readThreadParams *readParams = context; 

    pthread_mutex_lock(&readParams->b.mutexBuffer); 
    //<snip> 
    pthread_mutex_unlock(&readParams->b.mutexBuffer); 

    return NULL; 
} 

int main(void) { 
    int ret; 
    char *out_array = malloc(42); 
    size_t in_size = 42; 

    struct readThreadParams readParams; 
    readParams.b = buffer2; 
    readParams.data = out_array; 
    readParams.count = in_size; 

    /* I presume that by "buffer", you really meant the .b member of 
    * struct readThreadParams. Further, this must have a member 
    * named readThread of type pthread_t, etc. 
    */ 
    ret = pthread_create(&readParams.b.readThread, NULL, bufferRead, &readParams); 

    if (!ret) { 
     pthread_join(&readParams.b.readThread, NULL); 
    } 

    free(out_array); 

    return ret; 
} 
+5

-1ローカル変数を別のスレッドに渡します。 –

+0

問題がないmain変数のローカル変数です。 mainを終了すると、プログラムは終了し、プログラムが実行されている間は常に変数が存在します。 – jcoder

+1

@jcoder 'main'を残しても、プログラムが即座に終了するわけではありません。また、スレッド間通信のための自動(非ヒープ、非静的)変数は、最高で疑わしいアイデアです。 –

1

あなたは正しい方法で手に入れました。

関数のプロトタイプは

void* bufferRead(void *arg) 
{ 
    .... 
} 

ようになり、スレッド機能に必要な型に引数を型キャストする必要があります。ここでは、それはする必要があります

void* bufferRead(void *arg) 
{ 
    struct readThreadParams *input = (struct readThreadParams*)arg; 
} 

pthread関数に複数の引数を渡すことは直接できません。そのほとんどは構造体として形成され、関数に渡されます。

pthreadsの詳細についてはthisチュートリアルを参照してください。

+0

お返事ありがとうございました!疑問に思っていますが、現在持っている関数プロトタイプを使用する方法はありますか? – ChrisDevWard

+0

をタイプキャストして作成することができます。しかし、使用しないでください。 'void *()(void *)'を推奨します。 – Jeyaram

+0

@ChrisDevWardいいえ、できません。そのプロトタイプを使用する唯一の方法は、pthreadライブラリが呼び出すvoid * start_routine(void *)関数から直接呼び出すことですが、別の関数呼び出しのオーバーヘッドを不必要に導入することになります。 –

4

開始関数は引数をとる必要があります。だからあなたの方向は右である:

struct readThreadParams {             
    BoundedBuffer *b; 
    char *data;                
    int count;                
};  

次に、あなたがいないスタック上に、ヒープ上の変数を割り当てる必要があります:あなたはそれをcreateThreadを与えることができ

struct readThreadParams *readParams; 

readParams = malloc(sizeof(*readParams)); 
readParams->b = buffer2;              
readParams->data = out_array;             
readParams->count = in_size; 

た後:

pthread_create(&buffer.readThread, NULL, bufferRead, readParams); 

スレッド関数は1つの引数(void *)しか取らない:

void *bufferRead(void *arg) 
{ 
    struct readThreadParams *params = arg; 
    BoundedBuffer *buffer = params->b; 
    char* data = params->data; 
    int count = params->count; 

    pthread_mutex_lock(&buffer->mutexBuffer); 
    <snip> 
    pthread_mutex_unlock(&buffer->mutexBuffer); 

    return NULL; 
} 
0

この例では、プリプロセッサの悪用の境界線がありますが、デフォルトの引数値を模倣しているため、好きです。

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

typedef char *BoundedBuffer; 

struct read_thread_param { 
    pthread_t thread;             
    BoundedBuffer buffer;               
    char* data;                
    int count;                
}; 

void buffer_read(BoundedBuffer* buffer, char* data, int count) { 
    pthread_mutex_lock(&buffer->mutexBuffer); 
    /*snip*/ 
    pthread_mutex_unlock(&buffer->mutexBuffer); 
} 

void *buffer_read_entrance(void *object) { 
    struct read_thread_param *param = object; 
    if (param->thread != 0) { 
     buffer_read(&param->buffer, param->data, param->count); 
     free(param); 
     return NULL; 
    } 

    param = malloc(sizeof *param); 

    /* TODO: Handle allocation error */ 
    assert(param != NULL); 

    memcpy(param, object, sizeof *param); 

    /* TODO: Handle thread creation error */ 
    assert(pthread_create(&param->thread, NULL, buffer_read_entrance, param) == 0); 
    return NULL; 
} 

#define buffer_read_entrance(...) buffer_read_entrance(&(struct read_thread_param) { .thread = 0, __VA_ARGS__ }) 
void buffer_read(BoundedBuffer* buffer, char* data, int count); 

int main(void) { 
    buffer_read_entrance(.buffer = "hello world", .count = 42); 
} 
関連する問題