【问题标题】:Thread-safety vs atomicity in CC中的线程安全与原子性
【发布时间】:2019-10-02 15:17:08
【问题描述】:

据我所知,可以调用线程安全函数而不需要互斥或信号量。他们不能吗?

例如,strcpy()strdup() 是一种线程安全函数。

但是当我阅读手册页时,我看到以下内容并且不理解该说法以及粗体示例。

MT-Safe 并不意味着函数是原子的,也不意味着它是原子的 使用任何内存同步机制 POSIX 暴露给用户。甚至可以调用 MT-Safe 按顺序执行的功能不会产生 MT-Safe 组合。 例如,让一个线程调用两个 MT-Safe 函数之一 紧随其后不保证行为等同 原子执行这两个函数的组合,因为 其他线程中的并发调用可能会干扰 破坏性的方式。

线程函数中的以下用法是否错误?如果是,有哪些错误点?如果不是,加粗的那句话是什么意思?

char *s1 = calloc(14, 1);
char *s2 = calloc(6, 1);
char *s3 = strdup("soner");
char *s4 = strdup("stackoverflow");
strcpy(s2, s3);
strcpy(s1, s4);
s1[13] = s2[5] = 0;

mutex_lock(&mtx);
printf("%s %s", s1, s2);
fflush(stdout);
mutex_unlock(&mtx);

free(s1);
free(s2);
free(s3);
free(s4);

【问题讨论】:

  • 只是说使用线程安全函数来实现你的算法并不能使你的算法线程安全。
  • Re,“strcpy()...有点线程安全。”不,strcpy()strdup() 不是线程安全,它们是线程不可知。这些函数访问的唯一内存位置是它们自己的局部变量,以及程序提供指针的位置。如果您的线程不提供指向 shared 缓冲区的指针,那么在调用 strcpy()strdup() 时,将不需要线程安全,因为不会发生冲突。另一方面,如果您的线程确实提供了指向共享数据的指针,那么确保安全是您的责任。
  • 我很想听听“有点线程安全”的定义,它和“有点怀孕”一样吗?

标签: c multithreading unix thread-safety


【解决方案1】:

此处的“MT-Safe”仅表示您可以从多个线程调用该函数,而不是线程之间有任何同步。

例如,您有两个线程,其中一个正在执行strcpy(s1, "foo"),另一个正在执行strcpy(s1, "bar")(并且s1 是线程之间共享的缓冲区),那么您将遇到数据竞争,因为两个线程都可以尝试同时写入目的地s1

【讨论】:

  • ... 或者如果一个线程执行char s1[] = "foo"; strcpy(s1,"bar") 而另一个线程执行strcpy(s2,s1) 而没有同步,则不能保证s2 将获得"foo""bar" 的值,它也可能获得部分更改的值,例如"boo".
  • 如果 s1 是一个数组或指向 char 的指针,不是每个线程吗?因为它是在线程的函数中定义的,所以它在线程的堆栈中。 ??
  • @Bodo 我认为这是不可能的。 s1[]="foo" 在线程的堆栈空间中的事实确实意味着它对线程来说是特殊的。当另一个线程来时,它会做同样的事情。错了吗?
  • @Som.prog.du。如果缓冲区是共享的,那么竞争当然很明显。
  • @Bodo 只有且仅当 s2 是共享源时才有可能。
猜你喜欢
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-18
相关资源
最近更新 更多