2013-04-26 5 views
7

से थ्रेडेड फ़ंक्शन में एकाधिक तर्क पास करना यह सी में थ्रेडिंग का मेरा पहला प्रयास है। मैं एक गोलाकार रूप से बाध्य बफर बना रहा हूं। मैं कैसे धागा बनाने के लिए पता है, लेकिन सभी उदाहरण मैं केवल पिरोया है कार्यों कि एक शून्य पैरामीटर को स्वीकार देखा है, लेकिन दुर्भाग्य से मेरे कार्यकर्ता विनिर्देश मुझे तीन उपयोग करने के लिए की आवश्यकता है, जैसा कि यहाँ दिखाया: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/

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

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

कार्य कैसे struct के मापदंडों के प्रत्येक आवंटित करने के लिए पर कोई सलाह ख को पास करने के बाद ufferRead समारोह की सराहना की जाएगी।

उत्तर

8

ऐसा इसलिए है क्योंकि आप केवल एक पैरामीटर की आवश्यकता है। जब हमारे पास एक से अधिक मूल्य होते हैं, जैसा आम तौर पर मामला है, हम इसे एक संरचना में समाहित करते हैं। फ़ंक्शन प्रकार जो 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

पास करना यदि यह मुख्य में स्थानीय चर है जो कोई समस्या नहीं है। यदि आप मुख्य से बाहर निकलते हैं तो आपका प्रोग्राम वैसे भी समाप्त हो जाता है, इसलिए आपका प्रोग्राम चल रहा है, जबकि वेरिएबल हमेशा मौजूद है। – jcoder

+1

@jcoder 'मुख्य' छोड़ने का मतलब तत्काल प्रोग्राम समाप्ति का नहीं है। और इंटर-थ्रेड संचार के लिए स्वत: (गैर-ढेर, गैर स्थैतिक) चरणीय एक संदिग्ध विचार है। –

1

आपको सही तरीके से मिला है।

समारोह प्रोटोटाइप की तरह

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

हो और धागा समारोह में आवश्यक प्रकार के तर्क टाइपकास्ट चाहिए। यहां, यह

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

पाथ्रेड फ़ंक्शन के लिए एक से अधिक तर्कों को पास करना संभव नहीं है। इसलिए ज्यादातर संरचना के रूप में गठित और समारोह में पारित किया।

this ट्यूटोरियल पर अधिक जानकारी के लिए ट्यूटोरियल देखें।

+0

त्वरित उत्तर के लिए धन्यवाद! बस सोच रहा है, लेकिन अभी भी मेरे पास फ़ंक्शन प्रोटोटाइप का उपयोग करने का कोई तरीका है? – ChrisDevWard

+0

आप टाइपकास्ट और बना सकते हैं। लेकिन कोई उपयोग नहीं है। तो 'शून्य *() (शून्य *)' अनुशंसित है। – Jeyaram

+0

@ChrisDevWard नहीं, आप नहीं कर सकते।खैर, उस प्रोटोटाइप का उपयोग करने का एकमात्र तरीका यह है कि इसे सीधे अपने शून्य * start_routine (शून्य *) फ़ंक्शन से कॉल करें जिसे पर्थ्रेड लाइब्रेरी कॉल करेगी, लेकिन वह किसी अन्य फ़ंक्शन कॉल के ओवरहेड को अनिवार्य रूप से पेश करेगी। –

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 *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); 
} 
संबंधित मुद्दे