7

これは、C でスレッド化する最初の試みです。循環境界バッファーを作成しています。私はスレッドの作成方法を知っていますが、私が見たすべての例には、1 つの void パラメーターを受け入れるスレッド化された関数しかありませんが、残念ながら、私のワーカーの仕様では、次に示すように 3 つを使用する必要があります。

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/assignments

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

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

bufferRead 関数に渡した後に構造体の各パラメーターを割り当てる方法についてのアドバイスは大歓迎です。

4

4 に答える 4

11

これは、実際に必要なパラメーターは 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;
}
于 2013-04-26T07:26:55.523 に答える
4

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

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

次に、変数をスタックではなくヒープに割り当てる必要があります。

struct readThreadParams *readParams;

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

その後、あなたはそれを与えることができますcreateThread

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;
}
于 2013-04-26T07:11:14.787 に答える
2

あなたは正しい方法で得ました。

関数プロトタイプは次のようになります

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

そして、引数をスレッド関数で必要な型に型キャストします。ここでは、

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

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

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

于 2013-04-26T07:09:09.873 に答える
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);
}
于 2013-04-26T10:58:30.250 に答える