2017-05-19 1 views
-1

C에서 스레드 풀을 만들려고합니다. 각 스레드를 인수로 사용하는 조인 함수를 구현해야합니다. 본질적으로 thread_join 함수와 유사합니다. 아무도 간단한 스레드 가입 기능을 구현하는 방법에 관한 리소스를 제공 할 수 있습니까?스레드 풀 조인 기능

//structure that contains a pthread 
struct ThreadID; 

// from this run method I am creating threads in a thread pool 
int ThreadPool_run(struct ThreadPool *, struct ThreadID *, void *(*run)(void *), void *); 

// this is the join function 
int ThreadPool_join(struct ThreadID, void **); 
+0

스택 오버플로에 오신 것을 환영합니다. 곧 [About] 및 [Ask] 페이지를 읽으십시오. 작업중인 플랫폼과이 밑에서 사용할 계획이있는 스레드 라이브러리에 대해 좀 더 구체적으로 설명해야합니다. Unix (POSIX pthreads)와 Windows에서는 스레드간에 큰 차이점이 있으며 C11 표준은 명목상 스레드 지원을 가지고 있지만 항상 구현되는 것은 아닙니다. 또한 책, 도구, 소프트웨어 라이브러리, 자습서 또는 기타 오프 사이트 리소스를 추천하거나 찾도록 요청하는 _questions는 독창적 인 답변과 스팸을 유치하는 경향이 있으므로 스택 오버플로에 대해 논쟁의 여지가 없습니다 ._ –

+0

스레드 풀에 간신히 가입하십시오 어떤 의미. 당신은 java의'ExecutorService'와 C#'ThreadPool'이 어떻게 작동하는지 확인할 수 있습니다. 참여할 수있는 미래 또는 타스크 오브젝트를 리턴합니다. 실행을 멈추지 않으므로 (다른 작업을 실행 중일 때) 스레드 풀의 스레드에 참여하지 않습니다. – sturcotte06

답변

2

스레드 풀의 개념을 완전히 이해하고 있는지 잘 모르겠습니다. 쓰레드 풀 인터페이스에서 쓰레드가 들어가거나 빠져 나가는 개념을 가지고 있으면 안된다. 사실, 나는 자바의 ExecutorService 이름을 선호한다. 개념을 더 잘 캡슐화합니다. 기본적으로 스레드 수명을 걱정하지 않고 비동기 적으로 작업을 실행하려고합니다.

typedef struct executor executor_t; 
typedef struct executor_options executor_options_t; 
typedef struct executor_task executor_task_t; 
typedef struct blocking_queue blocking_queue_t; 
typedef struct future future_t; 
typedef void *(*task_t)(void* data); 

int executor_init(const executor_options_t options); 
int executor_submit(const executor_t *const executor, future_t *const future, const task_t task, const void *const data); 
int executor_destroy(const executor_t *const executor); 

int blocking_queue_init(blocking_queue_t *const queue); 
int blocking_queue_enqueue(const blocking_queue_t *const queue, const void *const data); 
int blocking_queue_dequeue(const blocking_queue_t *const queue, const void ** data); 
int blocking_queue_destroy(const blocking_queue_t *const queue); 

int future_init(future_t *const future); 
int future_wait(const future_t *const future); 
int future_destroy(const future_t *const future); 

구조는 다음과 같습니다 :

struct executor_options { 
    int min_thread; 
    int max_thread; 
    int max_idle_ms; 
}; 

struct executor { 
    pthread_mutex_t mutex; 
    pthread_t *threads; 
    executor_options_t options; 
    blocking_queue_t *queue; 
}; 

struct executor_task { 
    task_t task; 
    void *data; 
    future_t *future; 
}; 

struct blocking_queue { 
    executor_task_t *tasks; 
    pthread_mutex_t mutex; 
    pthread_cond_t empty; 
    pthread_cond_t full; 
    bool_t is_empty; 
    bool_t is_full; 
}; 

struct future { 
    void *result; 
    pthread_mutex_t mutex; 
    pthread_cond_t computed; 
    bool_t is_computed; 
}; 

executor_init에서, 당신은 모든 스레드를 초기화 할

이러한 서비스는 다음과 같습니다 인터페이스를 가질 것이다. 이러한 스레드는 작업을 대기중인 대기열에서 차단하고이를 실행하고 미래의 상태를 알려주어 대기자를 차단 해제해야합니다. executor_submit에서 주어진 미래를 초기화해야하며 작업은 미래와 함께 작업자가 비동기 적으로 계산하도록 대기열에 넣어야합니다. 그런 다음 미래는 작업 결과를 기다리기 위해 사용자가 사용할 수 있어야합니다. 마지막으로 executor_destroy은 남아있는 모든 작업이 계산 될 때까지 기다려야하므로 새로운 작업이 제출되지 않습니다. 마침내 모든 리소스를 해제하고 반환합니다.