首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C中重入和重入?

在C中重入和重入?
EN

Stack Overflow用户
提问于 2015-06-05 06:21:02
回答 4查看 2.1K关注 0票数 7

我正在读一本叫做Linux系统编程的书。引用这本书的话:

系统调用和其他库函数呢?如果您的进程正在编写文件或分配内存,而信号处理程序写入同一个文件或调用malloc()怎么办?有些功能显然不是可重入的。如果一个程序正在执行一个不可重入的函数,并且发生了一个信号,那么信号处理程序就会调用这个不可重入的函数,就会产生混乱。

但接下来会是:

保证-重入函数 保证在信号中使用的安全重入函数 这里有些功能..。 写() 这里有些功能..。

我很困惑,write()是可重入的吗?因为我认为这与声明相抵触:

如果您的进程正在写入文件的过程中呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-06-05 07:08:02

为了补充@Joachim Pileborg先生在他的回答中已经提到的内容,根据wiki条目,函数可重入的基本规则是

  1. 可重入代码可能不包含任何静态(或全局)非常数数据。
  2. 可重入代码不得修改自己的代码。
  3. 可重入代码不能调用不可重入的计算机程序或例程.

为了详细说明,这个函数,如果是重入的,无论是从不同的上下文调用,它自己的实现(诱导它自己使用的内部数据结构)都不会有任何问题。

提供给函数的参数(例如文件描述符)不会影响函数的重入性。

因此,对于write(),函数本身是可重入的,但是如果使用来自不同线程的相同的文件描述符调用,显然会产生错误的结果。同样,这并不意味着write()的可再入性已经消失。它是可重入的,但不是线程安全的,这两个方面是不同的。

票数 7
EN

Stack Overflow用户

发布于 2015-06-05 06:34:14

如果您可以从不同的上下文调用一个函数,而不干扰来自另一个上下文的另一个调用,那么可重入性还有更多的工作要做。

例如,strtok函数。它通常包含一个static局部变量,以跟踪要标记的字符串中的下一个位置。由于对函数的所有调用都共享本地static变量,因此从两个不同的上下文调用该函数将导致问题。

另一方面,write系统调用没有存储在调用之间的这样的内部数据,这使得从不同上下文调用是安全的。

需要注意的是,重入并不等同于线程安全。以write函数为例,因为它是可重入的,所以您可以使用不同的文件从不同的线程调用它,而不必担心内部数据会被破坏。然而,它并不是线程安全。使用相同的文件描述符从不同的线程调用它将导致问题。

票数 7
EN

Stack Overflow用户

发布于 2015-06-05 07:05:05

引用的文档指的是信号处理程序。这是一个非常特定于的函数类型,在特殊情况下被调用,并且被认为是特定的系统编程。他们违抗程序中的正常控制流程。

如果您没有编写信号处理程序,那么这个文档实际上对您没有用处。然而,下面列出了在Mac上信号安全的函数列表:

代码语言:javascript
复制
$ man sigaction

The following functions are either reentrant or not interruptible by
signals and are async-signal safe.  Therefore applications may invoke
them, without restriction, from signal-catching functions:

Base Interfaces:

_exit(), access(), alarm(), cfgetispeed(), cfgetospeed(),
cfsetispeed(), cfsetospeed(), chdir(), chmod(), chown(), close(),
creat(), dup(), dup2(), execle(), execve(), fcntl(), fork(),
fpathconf(), fstat(), fsync(), getegid(), geteuid(), getgid(),
getgroups(), getpgrp(), getpid(), getppid(), getuid(), kill(),
link(), lseek(), mkdir(), mkfifo(), open(), pathconf(), pause(),
pipe(), raise(), read(), rename(), rmdir(), setgid(), setpgid(),
setsid(), setuid(), sigaction(), sigaddset(), sigdelset(),
sigemptyset(), sigfillset(), sigismember(), signal(), sigpending(),
sigprocmask(), sigsuspend(), sleep(), stat(), sysconf(), tcdrain(),
tcflow(), tcflush(), tcgetattr(), tcgetpgrp(), tcsendbreak(),
tcsetattr(), tcsetpgrp(), time(), times(), umask(), uname(),
unlink(), utime(), wait(), waitpid(), write().
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30659646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档