2012-03-02 2 views
1

시뮬레이션 된 시간 실행을 사용하여 시스템을 구축하려고했는데 (semaphore로 스레드 조정), 아이디어는 모든 작업주기를 1 초로 만들고 정확한 시뮬레이션을 수행했습니다. 쓰레드는 다른 모든 쓰레드가 현재 시뮬레이션 된 초에 실행을 끝내기를 기다려야한다.pthread_join() 및 고정 실행

주 스레드가 다른 스레드 (초보자 실수)에 합류하지 않고 작업을 완료했기 때문에 나는 정말로 성가신 메모리 누수가있었습니다. 그래서 해결하기 위해 모든 스레드에 대해 pthread_join() 지침을 추가했습니다. 모든 스레드 실행은 확인하기위한 전역 조건이있는 while 루프 안에 있었기 때문에 메인 스레드가 완료 전에 변경했습니다. 슬프게도, 이제는, 프로그램의 대부분이 실행되면서, 스레드가 끝나기를 기다리고 얼어 붙습니다.

모든 스레드 실행을 끝내고 전체 작업을 무시하는 방법을 찾아야하지만 조인이 만들어 졌는지 (메모리가 해제되었는지) 확인해야합니다.

가 지금은 오류와 컴파일 가능한 코드를 게시, 당신은 샘플 -o의 gcc로 컴파일 할 수 있습니다 -pthread sample.c에 -lm

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 
#include <pthread.h> 
#include <semaphore.h> 
#include <math.h> 

#define SIZE 100 
#define READY 12345 
#define END 99 
#define TIME 3600 
int *advicer; 
int *td; 
pthread_t *phones; 
sem_t *counter; 
int ready; 
int end; 

void cycle(int cycles){ 
    int i,j,k; 
    for(i = 0; i < cycles; i++){ 
     k = 1; 
     while(k){ 
      k = 0; 
      for(j = 0; j < SIZE; j++){ 
       if(advicer[j] == 0){ 
        k = 1; 
        break; 
       } 
      } 
     } 
     for(j = 0; j < SIZE; j++){ 
      advicer[j] = 0; 
      sem_post(&counter[j]); 
     } 
    } 
} 

void *do_something(void *td){ 
    int t; 
    t = *((int *) td); 
    while(end != END){ 
     if(end == END) 
      break; 
     t += t; 
     advicer[t] = 1; 
     sem_wait(&counter[t]);  
    } 
    pthread_exit(NULL); 
} 

void all_free(){ 
    int i,j; 
    end = END; 
    printf("reach %d\n",end); 
    for(i = 0; i < SIZE; i++) 
     sem_post(&counter[i]); 
    printf("reach2\n"); 
    for(i = 0; i < SIZE; i++){ 
     pthread_join(phones[i],NULL); 
    } 
    free(phones); 
    printf("reach3\n"); 
    for(i = 0; i < SIZE; i++) 
     sem_destroy(&counter[i]); 
    free(counter); 
    free(td); 
    free(advicer); 
} 

void main(){ 
    int i,my_count; 
    counter = (sem_t *)malloc(sizeof(sem_t)*SIZE); 
    advicer = (int *)malloc(sizeof(int)*SIZE); 
    td = (int *)malloc(sizeof(int)*SIZE); 
    phones = (pthread_t *)malloc(sizeof(pthread_t)*SIZE); 
    for(i = 0; i < SIZE; i++){ 
     sem_init(&counter[i], 0, 0); 
     advicer[i] = 0; 
    } 
    ready = READY; 
    my_count = 0; 
    end = 0; 
    for(i = 0; i < SIZE; i++){ 
     td[i] = i; 
     pthread_create(&(phones[i]), NULL, do_something, (void *)(&td[i])); 
    } 
    printf("starting simulation\n"); 
    while(my_count < TIME){ 
     cycle(60); 
     printf("hello\n"); 
     my_count += 60; 
    } 
    printf("simulation ended\n"); 
    all_free(); 
} 
+2

실제 코드에 가까운 코드는 코드가 설명하는 것보다 의사 소통하는 것이 훨씬 낫습니다. 작은 세부 사항은 스레딩에 많은 영향을 미칩니다. –

+0

'정말 귀찮은 메모리 누수가있었습니다.'- 어떻게 알았습니까? 그리고 어떤 OS를 실행하고 있었습니까? 대부분의 OS/crt에서 주 스레드를 종료하면 프로세스가 종료되므로 모든 스레드가 종료되고 모든 메모리가 해제됩니다. –

+0

@MartinJames 왜냐하면 메모리 누수를 찾기 위해 valgrind를 사용했기 때문에 posix 스레드의 워드 프로세서를 찾았습니다. 왜냐하면 아무런 일도 일어나지 않을 경우 pthreads가 기본적으로 joinable이되기 때문에 일어날 것으로 예상됩니다. 좋은 자유를 만들기 위해 합류하십시오. BTW는 리눅스입니다. – Mig

답변

2

다음 절에서는 잠금으로 이어질 수 :

다른 사람이 종료되지 않는 한
for(i = 0; i < m->pp; i++) 
    sem_post(&counter[i]); 
for(i = 0; i < m->pp; i++){ 
if(m->ppl[i] != NULL){ 
    phone_free(m->ppl[i]); 
} 
... 
} 

당신은 BECA, 하나 개 모두 차단하는 모든 스레드 (잠금을 해제)에만 스레드 다음 (phone_free()를 통해) pthread_join() 부르지 만, 당신이 sem_post()라는 하나 sem_post() 전화 sem_wait()에서 붙어 사용하십시오.

당신은 주요 실행 ( cycle()) 값은 이전에 최종 실행 코드 ( map_free()) pthread_join() ( phone_free()를 통해)에 전화로 스레드에 의해 인출되었을 수 있습니다 동안 sem_post()라고하지만.

스레드를 취소하려면 pthread_cancel()을 사용할 수 있습니다.

스레드가 남아 있고 pthread_join()을 호출하지 않을 때 메모리 누수를 방지하려면 pthread_detach()을 사용하여 스레드를 분리 할 수 ​​있습니다. 그런 다음 OS는 스레드가 종료 될 때 스레드의 모든 자원을 해제합니다.

+0

형식이 잘못된 코드에 속았습니다. 중첩 된 루프 집합이 없습니다. 'sem_post()'호출은 첫 번째'for' 루프에 대한 유일한 명령문이므로 모든 세마포어는 '합류'루프로 이동하기 전에 '게시'됩니다. –

+0

@Michael Burr : Dxmn ... - 네 말이 맞아. 여하튼이 건축물은 자물쇠로 이어질 수있는 경쟁 조건을 도입합니다. 저는 제 대답을 바로 잡을 것입니다. 고마워. – alk

+0

나는 그 업데이트가 옳지 않다고 생각한다. 'sem_post()'호출 후에 일어나는 모든 스레드는'end == END'를보고'while' 루프를 종료합니다. 'sem_wait()'는 메모리 장벽이고'end'는 전역 변수이기 때문에 스레드는'end' 변수를 다시 읽어야합니다. 메인 쓰레드가 상응하는'pthread_join()'에 도착하기 전에 작업자 쓰레드가 종료 되더라도 조인은 성공적으로 완료된다. –

관련 문제