【问题标题】:C program concurrency with pthreadC 程序与 pthread 的并发性
【发布时间】:2011-12-14 18:37:20
【问题描述】:


我正在对教授的讲义进行复习。当我到达并发部分时,我得到了这个问题:
在幻灯片中,教授给出了两个使用 pthread 的例子(一个是好例子,一个是坏例子)。但我不明白为什么它们之间存在差异。
这是一个很好的例子:

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
void *get_rand_num(void *args) { 
  int *nump = malloc(sizeof(int)); 
  srand(pthread_self()); 
  *nump = rand(); 
  return nump; 
} 
int main() { 
  pthread_t tid; 
  void *ptr = NULL; 
  pthread_create(&tid, NULL, get_rand_num, NULL); 
  pthread_join(tid, &ptr); 
  printf("Random number: %d\n", * (int *) ptr); 
  return 0; 
}

糟糕的例子是

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
void *get_rand_num(void *args) { 
  int num; 
  srand(pthread_self()); 
  num = rand(); 
  return &num; 
} 
int main() { 
  pthread_t tid; 
  void *ptr = NULL; 
  pthread_create(&tid, NULL, get_rand_num, NULL); 
  pthread_join(tid, &ptr); 
  printf("Random number: %d\n", * (int *) ptr); 
  return 0; 
}

谁能理解这两个例子,请给我解释一下为什么坏的和第一个不一样,为什么不好?


谢谢
艾伦

【问题讨论】:

    标签: c multithreading concurrency pthreads


    【解决方案1】:

    这个不好的例子返回一个指向局部变量的指针。这总是一个坏主意,因为当函数返回时局部变量会死掉。这不是多线程程序特有的问题,但由于线程每个线程获得一个堆栈,该堆栈在pthread_join 之后被释放,所以问题更加严重。虽然你经常在单线程编程中很幸运,并且可以在函数返回后立即使用指针,但在坏例子中,包含旧线程堆栈的整个段可能已经回到操作系统,访问会产生分段错误。

    第一个例子也不是很好,因为它会产生内存泄漏。

    【讨论】:

    • 谢谢,我想我明白了!顺便说一句,在第一个示例中,您的意思是应该通过添加一行来释放分配的内存来改进它吗?比如free(nump)?你认为我应该把这条线放在程序的什么地方?我应该把它放在pthread_join()之前吗?
    • 从技术上讲,由于程序是短暂的,并且在程序终止时操作系统会自动回收内存,因此没有内存泄漏,只是不好的做法。
    • @AllanJiang:不,绝对不是。始终遵循简单的规则:malloc,使用内存,完成后,free。把它放在printf 调用之后。
    【解决方案2】:

    在不好的情况下,返回 &num,其中 num 是堆栈上的局部变量,仅在函数范围内有效。一旦返回,它就不再有效。

    【讨论】:

      【解决方案3】:

      坏情况返回一个指向堆栈位的指针 - 就像很久以前飞出窗外的鸟!

      但如果它有效 - 你将有一个非常非常随机的数字 - 比使用线程 id saltting 随机数生成器好一点!

      【讨论】:

      • 实际上,它可能不太随机,因为它直接引用另一个程序可以访问的内存中的位置(攻击向量)。
      • 很高兴这里的人有点幽默。无论哪种方式,我都可以很好地猜测那个 random 数字
      • 确实很幽默;只是指出一些有趣的事情。 :-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      • 2018-08-24
      • 2012-04-13
      • 1970-01-01
      相关资源
      最近更新 更多