【问题标题】:Multithreading with Strings in CC中的字符串多线程
【发布时间】:2014-10-19 06:20:23
【问题描述】:

我的代码有问题,也许你们中的某个人可以帮助我。 让我们试着做个短... 我有一个学校项目要做,它需要管道和线程(PL=C,SO=Debian)。程序运行良好,除了一个小错误让我无法入睡。

我把我的“线程”用于程序的文件访问,所以......它只需要打开文件,保存数据,并将文件部分的“报告”保存在字符串中,所以'shell' 可以将其显示给用户。

但问题是,如果我在线程内打印字符串(全局),字符串有数据,并且它被打印,但如果我让在“程序的外壳部分”中打印,则字符串为空,根本没有数据...下面是代码的关键部分,如果有人可以帮助我,我将非常感激。 顺便说一句,对不起我的英语,不是我的母语。

那是线程函数

void *acessaDisco(void *arg)
{
    int op;
    op = (int) arg;

    switch(op)
    {
        case 1:
            //salva no disco
            //sem_wait(&semaforoControleTextoThread);
            if(escrevePersonagemArquivo(personagemTempThread)==TRUE){
                pthread_mutex_lock(&tranca);
                sprintf(textoThread,"\n\nSeu personagem foi salvo corretamente!\n\n");
                pthread_mutex_unlock(&tranca);          
            }
            else{
                pthread_mutex_lock(&tranca);
                sprintf(textoThread,"\n\nOcorreu um erro ao tentar salvar seu personagem...\n\n");
                pthread_mutex_unlock(&tranca);
            }
            //sem_post(&semaforoControleTextoThread);
            break;
        case 2:
            //encontra personagem no arquivo
            //sem_wait(&semaforoControleTextoThread);
            if(encontraPersonagem(nomeBuscaPersonagem,&personagemTempThread)==FALSE){
                pthread_mutex_lock(&tranca);
                sprintf(textoThread, "\n\nInfelizmente, o personagem %s não foi encontrado... :(\n\n", nomeBuscaPersonagem);
                pthread_mutex_unlock(&tranca);
            }
            else{
                pthread_mutex_lock(&tranca);
                imprimeFichaTemp(personagemTempThread, textoThread);
                strcpy(auxiliarTeste, textoThread);
                pthread_mutex_unlock(&tranca);
                //printf("\n\n\nDepois bloquear mutex, string: %s", textoThread);
            }
            //sem_post(&semaforoControleTextoThread);
            break;
    }

    return NULL;

}

这里是我调用它的地方...

case 300:
        //procura o personagem
        strcpy(nomeBuscaPersonagem, buff+4*sizeof(char));
        pthread_create(&threadAcessaDisco, NULL, acessaDisco, (int)2);
        break;

最后,我在哪里打印它

case 2:
            fflush(stdout);
            fflush(stdin);
            printf("\n\nAntes Tela Visualizacao\n\n");
            telaVisualizacao(writefd);
            fflush(stdout);
            fflush(stdin);
            printf("\n\nAntesSemWaitClient\n\n");
            //sem_wait(&semaforoControleTextoThread);
            printf("\n\nDepoisSemWaitClient\n\n");
            fflush(stdout);
            fflush(stdin);
            pthread_mutex_lock(&tranca);
            printf("\n\nTexto Thread:%s Texto aux: %s\n\n", textoThread, auxiliarTeste);
            pthread_mutex_unlock(&tranca);
            fflush(stdout);
            fflush(stdin);
            //sem_post(&semaforoControleTextoThread);
            getchar();
            break;

如果需要任何其他信息,我很乐意提供!

提前致谢!!

【问题讨论】:

  • stdin 上执行fflush 在技术上是未定义的行为,它是某些库中的扩展,但是如果您想保持代码的可移植性,则不应这样做。此外,stdout 默认是行缓冲的,所以stdout 在打印换行符时会自动刷新,因此您不必这样做。最后,在那些支持在stdin 上执行fflush 的系统上,它只需要在您读取输入之前完成,而不是每次打印任何内容时完成。
  • 这里有很多不清楚的地方。您在case 300 上创建线程,但在case 2 上打印,显然没有创建线程。此外,您似乎没有等待线程准备好textoThread,然后再将其打印到任何地方。
  • 另外,您对nomeBuscaPersonagem 的使用不受保护,因此如果您为一个线程设置它,但在线程有机会使用它之前更改它,该线程将使用更新后的字符串.
  • 显然你试图在你的代码中使用信号量(你注释掉)。这很重要,你需要它们。我只是没有看到 sem_init() 被使用,这很重要。
  • 好吧,让我们分部分进行

标签: c string thread-safety pthreads mutex


【解决方案1】:

无法保证在您尝试检索值时线程已经执行。

您需要在主线程中使用信号量,该信号量等待您创建的线程。然后该线程需要发布到信号量,这让主线程知道它可以检索该值。

互斥锁是锁定原语:它们允许您保证对资源的互斥访问。它们本身不提供同步(顺序执行)。为此,您应该使用信号量。从 cmets 看来,您对此有所了解,但您无法让它发挥作用。

这是你的程序应该运行的顺序:

  1. 主线程:初始化信号量(为0),用指向信号量的指针创建目标线程。 sem_wait 在需要该值之前创建的信号量。执行将阻塞。
  2. 目标线程:设置共享(全局)值,发布到信号量。
  3. 主线程:现在在目标线程中初始化值后恢复执行,并且应该填充该值。

【讨论】:

  • 嗯...我对 POSIX 的解读是,信号量的值始终是 unsigned,因此将其初始化为 -1 对我来说看起来很狡猾。
  • 呃,我不知道这是怎么做到的。它应该说 0。已编辑。感谢您了解这一点。
  • 非常感谢您的提示 :) 但问题是我试图从另一个子进程访问字符串,我很傻 :D 无论如何,我将使用您的提示来完成项目现在。再次感谢!
猜你喜欢
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
相关资源
最近更新 更多