【问题标题】:Making this simple code threadsafe使这个简单的代码线程安全
【发布时间】:2013-07-04 02:36:17
【问题描述】:

我刚刚很好地使用了多线程。因此....我必须学习多线程。我有一个非常简单的程序:

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);
}

}

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

不出所料,实际上(对于我在这件事上的强者来说,很明显)输出是“一团糟”。

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

谢谢!

【问题讨论】:

  • 你的意思是输出搞砸了?看起来对我来说应该没问题。向我们准确展示它的功能以及您希望它做什么。也没有“事后”
  • 对不起,伙计们。修复了代码...

标签: c multithreading thread-safety


【解决方案1】:

因此,只需使用单个 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);

}
}

【讨论】:

  • 这并不能解决输入操作期间出现输出的问题,甚至无法编译。您通常应该检查您在此处发布的代码以确保其可用。
【解决方案2】:

在您的原始代码中,该代码中不应有“混乱”的输出(无论如何是由线程引起的),因为只有 one 线程(主线程)正在执行任何输出。

另一个线程所做的唯一事情就是无限循环并带有某种延迟。

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

有几种方法可以解决这个问题,有两种方法会立即浮现在脑海中。

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

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

【讨论】:

  • 这不是一个真正的答案,应该只是一个评论。
  • @xaxxon,它一个答案,说明 OP 认为正在发生的事情不可能发生。在这方面有充分的先例。无论如何,既然问题已被编辑,我添加到答案中的额外信息使我认为这是一个有用的答案。希望你会同意。
  • 通常当这种情况发生时,它仅仅意味着他们错误地复制了一些代码。一个简单的注释说明代码没有按照他们所说的那样做通常被认为是正确的方法,因此正是这种类型的不回答的标志。
  • 首先你用“答案”复制我的评论,然后你重新发布我的答案?俗气。
  • xaxxon,建议你再看看。我的互斥锁解决方案不是按照您的那样在代码中添加锁,而是提供具有本地锁定的输出函数的修改实现,从而减少调用代码中对锁管理的需求。这只是两种可能性中的一种,这两种可能性都是由于问题编辑而不是您的答案而添加的。 ...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多