【问题标题】:cycle inside a thread在线程内循环
【发布时间】:2015-05-24 15:54:43
【问题描述】:

我创建了 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;
}

【问题讨论】:

  • 你在计数时使用了互斥锁吗?
  • 向我们展示passa_automovel 的代码和一个完整的工作/可重现示例。例如,您的计数是否是线程安全的?你何时/何地/如何观察这个计数器?您是否正确等待所有线程完成(例如 pthread_join())?在所有线程完成之前,您的程序可能已经存在。有多种选择。没有完整的工作示例很难说。
  • 或者更好——我们可以得到passa_automovel 的代码吗?它可能不是线程安全的,因此您会得到奇怪的结果。
  • 不管问题如何,传递(void*)vector_local[i] 都会将值转换为 i。我想你想要的是(void*)&amp;vector_local[i]
  • 顺便说一句:显示的代码未加入multa_thread

标签: c multithreading cycle


【解决方案1】:

知道了。您在 passa_automovel 中调用 pthread_exit。 这样,您将在第一个周期杀死线程。 删除它,它就可以工作了。

【讨论】:

  • 在这种情况下,可能值得一提的是,只有在函数想要返回指向加入线程的指针时才需要调用pthread_exit()。在所有其他情况下,使用return NULL 离开线程函数是完全有效的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-07
  • 2014-08-03
  • 2015-03-01
相关资源
最近更新 更多