2015-05-24 2 views
2

Я создал 100 потоковцикл внутри нити

int i; 
pthread_t threads[100]; 

for(i=0; i<100; i++) 
     pthread_create(&threads[i], NULL, analisa, (void*)vetor_local[i]); 

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

void* analisa(void* arg) 
{ 
    int i; 

    for (i = 0; i < 3; i++) 
    { 
    char *local1 = (char*) arg; 
    passa_automovel((void*) local1); 
    } 

    pthread_exit(NULL); 
} 

Это только вызывает функцию passa_automovel 100 раз вместо 300. Я поставил счетчик в passa_automovel, и он подсчитал только 100 вызовов.

Это полный код:

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
#include <sys/mman.h> 
#include <semaphore.h> 
#include <pthread.h> 
#include <string.h> 

#define POSTOS_CONTROLO 100 
#define CARROS 300 

typedef struct 
{ 
    int velocidade; 
    char matricula[20]; 
    char local[50]; 
} controlo; 

controlo postos_controlo[CARROS]; 
controlo infracoes[CARROS]; 
char vetor_local[POSTOS_CONTROLO][50]; 
pthread_mutex_t mux; 
int cont_controlo = 0, cont_infracoes = 0, multas_processadas = 0; 
pthread_cond_t cond_multa; 

void* passa_multa(void* arg) 
{ 

    /*garantir exclusao mutua no acesso a variavel de condiçao e ao contador*/ 
    pthread_mutex_lock(&mux); 
    while (cont_controlo != cont_infracoes) 
    pthread_cond_wait(&cond_multa, &mux); 

    infracoes[cont_infracoes] = postos_controlo[cont_controlo]; 
    multas_processadas++; 

    /*liberta zona de exclusao mutua*/ 
    pthread_mutex_unlock(&mux); 

    pthread_exit(NULL); 
} 

void* passa_automovel(void* arg) 
{ 

    char *local1 = (char*) arg; 
    time_t t; 
    srand((unsigned) time(&t)); 
    int i_matricula, velocidade; 

    i_matricula = rand() % 900; 
    char matricula[15]; 
    sprintf(matricula, "%d", i_matricula); 

    velocidade = rand() % 120; 

    /*garantir exclusao mutua no acesso a variavel de condiçao e ao contador*/ 
    pthread_mutex_lock(&mux); 

    postos_controlo[cont_controlo].velocidade = velocidade; 
    strcpy(postos_controlo[cont_controlo].matricula, matricula); 
    strcpy(postos_controlo[cont_controlo].local, local1); 

    if (velocidade > 70) 
    { 
    cont_infracoes++; 
    pthread_cond_signal(&cond_multa); 

    } 

    cont_controlo++; 

    pthread_mutex_unlock(&mux); 

    pthread_exit(NULL); 
} 

void* analisa(void* arg) 
{ 
    int i; 
    //char *local1=(char*)arg; 

    for (i = 0; i < 3; i++) 
    { 
    char *local1 = (char*) arg; 
    passa_automovel((void*) local1); 
    } 

    pthread_exit(NULL); 
} 

int main() 
{ 

    int i; 
    pthread_t threads[POSTOS_CONTROLO], multa_thread; 

    /*preencher o vetor de locais*/ 
    for (i = 0; i < POSTOS_CONTROLO; i++) 
    { 
    char str[15]; 
    sprintf(str, "%d", i); 
    strcpy(vetor_local[i], str); 
    } 

    pthread_cond_init(&cond_multa, NULL); 

    /*lancar postos de controlo (threads)*/ 
    for (i = 0; i < POSTOS_CONTROLO; i++) 
    pthread_create(&threads[i], NULL, analisa, (void*) vetor_local[i]); 

    /*criar thread passa multa*/ 
    pthread_create(&multa_thread, NULL, passa_multa, NULL); 

    /*esperar que threads terminem execucao*/ 
    for (i = 0; i < POSTOS_CONTROLO; i++) 
    pthread_join(threads[i], NULL); 

    for (i = 0; i < CARROS; i++) 
    { 
    printf("%d velocidade: %d matricula: %s  local: %s \n", i, 
     postos_controlo[i].velocidade, postos_controlo[i].matricula, 
     postos_controlo[i].local); 

    //printf("multas: %d \n", infracoes[i].velocidade); 

    } 

    printf("multas passadas: %d \n", cont_infracoes); 

    return 0; 
} 
+1

Вы использовали мьютексы при подсчете? – HAL9000

+0

Покажите нам код 'passa_automovel' и полный рабочий/воспроизводимый пример. Например, ваш подсчет в нем потокобезопасен? Когда/где/как вы наблюдаете этот счетчик? Правильно ли вы ожидаете завершения всех ваших потоков (например, pthread_join())? Возможно, ваша программа существует, прежде чем все потоки закончатся. Существует несколько вариантов. Трудно сказать без полного рабочего примера. –

+0

Или лучше - у нас есть код для 'passa_automovel'? Вероятно, это не потокобезопасно, и вы получаете странные результаты. –

ответ

4

Понял. Вы вызываете pthread_exit внутри passa_automovel. Таким образом, вы убиваете поток в первом цикле. Удалите его, и он работает.

+0

Да, именно так, спасибо. –

+2

Nice catch ... :-) – alk

+3

В этом контексте, возможно, стоит упомянуть, что вызов 'pthread_exit()' необходим только, если функция хочет вернуть указатель на соединительный поток. Во всех остальных случаях просто оставить функцию потока с помощью 'return NULL' совершенно допустимо. – alk

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