2012-01-23 4 views
2

Можно создать дубликат:
Multiple arguments to function called by pthread_create()?
How to pass more than one value as an argument to a thread in C?Переходя более одного параметра к pthread_create

У меня есть эти структуры:

struct Request { 
    char buf[MAXLENREQ]; 
    char inf[MAXLENREQ]; /* buffer per richiesta INF */ 
    int lenreq; 
    uint16_t port; /* porta server */ 
    struct in_addr serveraddr; /* ip server sockaddr_in */ 
    char path[MAXLENPATH]; 
    /*struct Range range;*/ 
}; 

struct RequestGet { 
    char buf[MAXLENREQ]; 
    int maxconnect; 
    struct Range range; 
}; 

struct ResponseGet{ 
    char buf[MAXLENDATA]; 
    //int LenRange; 
    int expire; 
    char dati[MAXLENDATA]; 
    struct Range range; 
}; 

Как я могу передать их pthread_create ? Независимо от значений каждой области структур.

pthread_create(&id,NULL,thread_func,????HERE????); 
+0

Я видел это, но мои сомнения было о таНосе трех различных структур ... – rschirin

+0

возможно дубликата [Несколько аргументов функции, вызываемой pthread_create()?] (Http://stackoverflow.com/questions/1352749 /), [pthreads и C++] (http://stackoverflow.com/questions/2468113/), [Передача нескольких аргументов в поток в C (pthread_create)] (http://stackoverflow.com/questions/6524433 /) – outis

ответ

6

Вы можете передать только один параметр, поэтому вам обычно нужно сделать функцию, которая принимает один параметр, даже если он просто переносит некоторые другие вызовы. Вы можете сделать это, создав struct и имея функцию, указав на такой struct.

Базовый пример, иллюстрирующий пункт, приведен ниже. Обратите внимание, что это не полный пример, и должен не использовать как есть! Обратите внимание, например, что ни одна из памяти, выделенная malloc(), не освобождается.

struct RequestWrapper { 
    struct Request *request; 
    struct RequestGet *request_get; 
    struct ResponseGet *response_get; 
}; 

void thread_func(struct RequestWrapper *rw) { 
    // function body here 
} 

int main(int argc, char *argv[]) { 
    struct Request *request = malloc(sizeof(*request)); 
    struct RequestGet *request_get = malloc(sizeof(*request_get)); 
    struct ResponseGet *response_get = malloc(sizeof(*response_get)); 
    ... 

    struct RequestWrapper *wrapper = malloc(sizeof(*wrapper)); 

    wrapper->request = request; 
    wrapper->request_get = request_get; 
    wrapper->response_get = response_get; 

    ... 

    pthread_create(&id, NULL, thread_func, &wrapper); 
    ... 
} 
+0

Опасно неполно. См. Мой комментарий к spraff. –

+0

@R .. Идея состоит в том, чтобы заставить его начать с концепции, которую он не понимает, а не писать целую кучу другого кода. Лучшими примерами являются, по общему признанию, те, которые работают как есть, но это дает представление о том, как передать несколько вещей, и я думаю, что это соответствует этому. Однако я добавлю примечание, указывающее на его незавершенность. –

+0

Ну, проблема в том, что вы «заставляете его начинать» с кода, который, вероятно, будет работать 99% времени и аварии или ужасно поврежденной памяти в 1% случаев. Начинающие вряд ли это осознают, а тем более знают, как вернуться и исправить это. –

0

Последний аргумент pthread_create() является указателем на пустоту. Его назначение состоит в том, что вы можете указать на любой тип переменной, структуру и т. Д. Ваш thread_func знает, как с ним справиться, и может вернуть его обратно к исходному типу.

0

Поместите свои адреса в struct и передайте указатель на это struct в качестве последнего аргумента pthread_create().

2
struct Foo { 
    // anything you want 
}; 

void run (void * _arg) { 
    Foo * arg = (Foo*) _arg; 
    // ... 
} 

int main() { 
    pthread_t thread; 
    Foo * foo = create_argument(); 

    pthread_create (&thread, NULL, run, foo); 
} 

Это зависит, конечно, по договору, который run всегда будет дан в последнем аргументе в Foo* к pthread_create.

+1

Этот ответ опасно незавершен; как написано, время жизни «foo» потенциально заканчивается до того, как «run» сможет его использовать. Вы должны либо выделить пространство для 'foo' с помощью' malloc' (и 'free' в новом потоке, а не в родительском потоке!) Или использовать некоторые объекты синхронизации (барьер или семафор проще всего), чтобы гарантировать, что' foo' ' s срок службы не заканчивается слишком рано. –

+0

Хорошая точка, отредактированная. – spraff

0

Вы можете просто создать структуру для всех данных и передать адрес структуры. вам может понадобиться поместить структуру в кучу и освободить ее, когда закончите.

Смежные вопросы