使这个简单的代码线程安全

时间:2013-07-04 02:36:17

标签: c multithreading thread-safety

我对多线程非常有用。因此....我必须学习多线程。我有一个非常简单的程序:

void *listenloop(void *arg){

    while (1){
       Sleep(2000);
       puts("testing 123\n");
   }
   return NULL;
}


int main(){
pthread_t listener;
pthread_create(&listener,NULL,listenloop,"foo");
char testinput[200];
while(1){
    puts("Scanning: ");
    scanf("%s",testinput);
    puts("\n\n");
    printf("You typed: %s: ",testinput);
}

}

理论上它等待用户输入,回声,同时定期打印。

没有让我感到意外的是,实际上(并且可能显然是对我在这件事上的更好)输出是“搞砸了。”

现在我可以想到围绕这个问题的几种方法,但没有实际的解决方案。应该如何实施这种性质的东西?它可以通过在程序输出显示给用户之后操作它来完成吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

在原始代码中,该代码中不应出现“混乱”输出(由线程引起),因为只有一个线程(主要线程)正在进行任何输出。 / p>

另一个线程唯一能做的就是无限循环,但有一些延迟。

既然您已将问题更新为从另一个线程输出,那么,是的, 可能使输出混合。

有几种方法可以解决这个问题,立即考虑两种方法。

  1. 让所有输出都通过一系列互连保护输出流的功能,例如mutexed_printf()/mutexed_puts()(您需要提供)(a)
  2. 完成一个线程的所有输出,这意味着另一个必须通过某种方式(线程间通信,如队列)向它发送数据 - 这样所有输出都可以正确混合,例如在换行边界上。

  3. (a)还要记住,如果你想互斥保护用户输入操作的输出流,你可能想要原子地保护puts/scanf以便测试输出不会弄乱您的输入(通过在提示之后但在输入之前/期间输出消息)。使用mutexed_puts()函数无法做到这一点,您需要扩展mutexed_prompt_and_input()个。

答案 1 :(得分:0)

所以只需使用一个pthread_mutex_t将打印件包装在pthread_mutex_lock / unlocks中,你就可以了。

http://linux.die.net/man/3/pthread_mutex_lock

pthread_mutex_t = PTHREAD_MUTEX_INITIALIZER; 

void *listenloop(void *arg){

    while (1){
       Sleep(2000);
       pthread_mutex_lock(&mutex);
       puts("testing 123\n");
       pthread_mutex_unlock(&mutex);
   }
   return NULL;
}


int main(){
pthread_t listener;
pthread_create(&listener,NULL,listenloop,"foo");
char testinput[200];
while(1){

    pthread_mutex_lock(&mutex);
    puts("Scanning: ");
    pthread_mutex_unlock(&mutex);

    scanf("%s",testinput);

    pthread_mutex_lock(&mutex);
    puts("\n\n");
    printf("You typed: %s: ",testinput);
    pthread_mutex_unlock(&mutex);

}
}