2013-04-26 11 views
7

'dan dişli işlevine birden çok argüman iletmek bu benim C'de iş parçacığı oluşturma ilk denememdir. Dairesel olarak sınırlanmış bir arabellek oluşturuyorum. İşte pthread_create

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

benim pthread_create geçerli: burada gösterildiği gibi, ben parçacığı oluşturmak için biliyorum, ancak tüm örnekler Bir boşluk parametresini kabul yalnızca dişli olan fonksiyonları gördük, ama ne yazık ki işçinin şartname üç kullanmamı istiyor ifadesi

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

Ve readParams yapı/b geçtikten sonra

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

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

yapı her parametresi atamak konusunda herhangi tavsiyelerde ödevi ufferRead işlevi büyük ölçüde takdir edilecektir.

cevap

8

Bunun nedeni, yalnızca gerçekten 'un tek bir parametreye gereksinim duymasıdır. Birden fazla değere sahip olduğumuzda, genelde olduğu gibi, bunu bir yapıda içine alırız. Pthread_create öğesinin çalacağı işlev türü pazarlık dışıdır. Bu, işlev göstericinizin sizi türüne çevirmesinin ciddi sorunlara neden olabileceği bir alandır.

#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 Bir yerel değişken başka bir iş parçacığına geçiriliyorsa, ana bir yerel değişken ise sorun değil. Ana programdan çıkarsanız, programınız yine de sona erer, böylece programınız çalışırken değişken her zaman var olur. –

+0

'a iletme – jcoder

+1

@jcoder 'main' bırakmak, programın sonlandırılması anlamına gelmez. İnter-thread iletişimi için otomatik (non-yığın, non-statik) değişken, en iyi ihtimalle şüpheli bir fikirdir. –

1

Doğru şekilde girdiniz.

fonksiyon prototip

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

gibi olmak Ve iplik işlevinde gerekli tipine argüman typecasting olmalıdır. Burada, pthread işlevine birden fazla argümanın aktarılması doğrudan mümkün olmamalıdır. Bu yüzden çoğunlukla yapı olarak oluştu ve işleve geçti.

pthreads hakkında daha fazla bilgi için this eğitimine bakın.

+0

Hızlı yanıt için teşekkürler! Sadece merak ediyorum, ama şu anda sahip olduğum fonksiyon prototipini kullanmanın bir yolu var mı? – ChrisDevWard

+0

yazım ve oluşturma yapabilirsiniz. Ama kullanamazsın. yani void *() (void *) 'önerilir. – Jeyaram

+0

@ChrisDevWard Hayır, yapamazsınız.Bu prototipi kullanmanın tek yolu, doğrudan pthread kütüphanesinin çalacağı void * start_routine (void *) fonksiyonundan çağırmaktır, ancak bu gereksiz bir şekilde başka bir fonksiyon çağrısının yükünü getirecektir. –

4

Başlatma işlevi bağımsız değişken almak zorunda. Yani yönü haklı:

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

Sonra değil yığın, yığın üzerinde değişkeni tahsis etmek gerekir: bunu createThread verebilir

struct readThreadParams *readParams; 

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

hangi sonra:

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

İş parçacığı işlevi yalnızca 1 bağımsız değişken (void *) alır:

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

Bu örnek önişlemci kötüye on sınırları, ancak varsayılan argüman değerleri taklit gösterdiği için seviyorum.

#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); 
} 
İlgili konular