问题标签 [posix]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 帮助了解基本线程概念/竞争条件
我现在正在学习 POSIX 线程,但我想这只是一个关于多线程的一般问题,所以我希望任何人都可以帮助我。我正在研究的书中有这个例子,它演示了一个竞争条件:
关于这个,有几件事我不明白。首先,“在线程号 5 中”。被打印了很多次,即使它不应该在线程号 5 中。在书中,示例显示线程 8 被打印了很多次。我也不明白说的部分*(int *)thread_number
。我尝试将其更改为仅 thread_number,但这只是一遍又一遍地给了我奇怪的数字。
这本书并没有真正解释这一点。有人可以清楚地解释这里发生了什么吗?我不明白为什么它不打印如下内容:
我知道这是因为它是多线程的“在线程号 x 中”。部分将在不同的时间出现,但我真的不明白为什么我创建的每个线程都没有 10 个“在线程编号 x”中一行!
~德西
serial-port - 使用 POSIX 访问半双工串口
我被要求使用 POSIX 调用读取和写入半双工串行连接(更具体地说,在 Linux 2.6.x 上用 C 语言编写)。我在查找有关该特定模型的详细信息时遇到了一些麻烦(大多数页面都集中在全双工上),并且由于阅读时出现轻微异常,我想检查一下我是否在这里做错了。
使用半双工串行连接,我只能读或写。这不是问题,因为线路上没有未经请求的传入数据 - 唯一一次将任何包裹发送给我(供阅读)是我事先要求它们时。
所以我的代码所做的就是在需要发送某些东西时将其写入()到端口。如果这些数据导致响应(我事先知道的),我只需读取()。我没有调用特殊函数 - 但也许我应该调用?这种方法正确吗?即当线路空闲时写?
signals - 我可以忽略除以零导致的 SIGFPE 吗?
我有一个程序故意执行除以零(并将结果存储在 volatile 变量中)以便在某些情况下停止。但是,我希望能够禁用这种暂停,而无需更改执行除以零的宏。
有没有办法忽略它?
我试过使用
但它仍然因消息“浮点异常(核心转储)”而死。
我实际上并没有使用该值,所以我并不真正关心分配给变量的内容;0、随机、未定义...
编辑:我知道这不是最便携的,但它适用于在许多不同操作系统上运行的嵌入式设备。默认停止动作是除以零;其他平台需要不同的技巧来强制看门狗引起的重启(例如禁用中断的无限循环)。对于 PC (linux) 测试环境,我想禁用除以零时的暂停,而不依赖于断言之类的东西。
c - strerror_r 应该允许多大的尺寸?
OpenGroup POSIX.1-2001 定义了strerror_r,Linux 标准基础核心规范 3.1也是如此。但是我找不到对错误消息可以合理预期的最大大小的参考。我希望有一些定义可以放在我的代码中,但我找不到。
代码必须是线程安全的。这就是为什么使用 strerror_r 而不是 strerror 的原因。
有人知道我可以使用的符号吗?我应该创建自己的吗?
例子
从文件:
开放组基本规范第 6 期:
错误
如果出现以下情况,strerror_r() 函数可能会失败:
- [ERANGE]通过 strerrbuf 和 buflen 提供的存储空间不足,无法包含生成的消息字符串。
从来源:
glibc-2.7/glibc-2.7/string/strerror.c:41:
posix - 更改系统时间对休眠线程有什么影响?
如果您看一下clock_gettime()函数,它在所有BSD 中都可用并且实际上被定义为POSIX 标准的一部分,您会发现至少支持三种类型的时钟(许多系统支持的时钟不止这些时钟) ,但实际上 POSIX 标准只要求存在一个,所有其他都是可选的):
CLOCK_REALTIME - POSIX 要求它存在。这是挂钟。
CLOCK_MONOTONIC - 不知道这是什么(以及 SI 秒的含义),但我知道这个时钟永远不会向后跳,它只能单调增加值。
CLOCK_UPTIME - 我看不出这与 CLOCK_MONOTONIC 有什么不同(正常运行时间也永远不会向后跳),但至少我知道内核启动时这个时钟从零开始(而它没有定义内核启动时 CLOCK_MONOTONIC 的初始值是多少) )
让我们暂时忽略其他时钟。CLOCK_REALTIME 不能保证单调向上计数,对吧?这是实际的“系统时间”。我可以随意更改系统时间。我可以将它设置为过去 3 个月或未来 5 年,每次我的系统使用网络上的 NTP 服务器同步时间时,时间可能会向前或向后跳跃。
现在我们在 BSD 系统中有两个休眠函数。sleep()和nanosleep()。我不确定,但我希望 sleep() 在 nanosleep 之上实现,毕竟我可以通过使用 nanosleep() 轻松模拟 sleep() 并且只在 struct timespec 中设置秒数,保持纳秒为零.
我在很多资料中读到,这些函数实际上是通过计算唤醒时间来工作的(获取当前时间,添加睡眠量),如果当前时间晚于唤醒时间,系统将定期检查时间,如果是这样,它将再次唤醒线程。仅在间隔中检查这一事实是手册页说当前睡眠将至少睡眠这段时间的原因(仅在被信号中断时更短),但它可能会睡眠更长时间(取决于多久系统检查我们是否已经超过了唤醒时间,并且取决于调度程序允许该线程再次运行之前需要多长时间)。
这对我来说是完全理智的......但是有一个问题一直困扰着我:
根据各种来源,睡眠(至少是 nanosleep)在内部使用 CLOCK_REALTIME 作为时钟。这意味着,如果告诉 nanosleep() 休眠 30 秒,然后将我的系统时钟更改为未来 1 小时,线程将几乎立即唤醒(未来 1 小时远早于唤醒时间 nanosleep( )计算)。这也完全没问题。但是,如果我说在 30 秒后醒来,然后用户发现他的系统时钟提前一小时并将他的时钟向后设置一小时,会发生什么?然后我的线程会休眠 1 小时 30 秒?因为那将是相当糟糕的。
c++ - pthread_join - 多个线程等待
使用 POSIX 线程和 C++,我有一个“插入操作”,一次只能安全地完成一个。
如果我有多个线程等待使用 pthread_join 插入,则在完成时生成一个新线程。他们是否都会一次收到“线程完成”信号并产生多个插入,或者假设首先收到“线程完成”信号的线程将产生一个新线程,阻止其他线程创建新线程。
感谢您的答复
该程序基本上是一个巨大的哈希表,它通过套接字接收来自客户端的请求。
每个新的客户端连接都会产生一个新线程,然后它可以从中执行多个操作,特别是查找或插入。查找可以并行进行。但是插入需要“重新组合”到一个线程中。您可以说查找操作可以在不为客户端生成新线程的情况下完成,但是它们可能需要一段时间导致服务器锁定,从而丢弃新请求。该设计试图尽可能减少系统调用和线程创建。
但现在我知道我最初认为我应该能够拼凑一些东西的方式并不安全
谢谢
c - 转换为多线程套接字应用程序
因为我目前只用 C 语言做这个项目,所以到目前为止我只将我的网络服务器用作单线程应用程序。不过,我不想再这样了!所以我有以下代码来处理我的工作。
现在我fork();
在开始之前添加了ProcessConnection();
这有助于我允许多个连接!但是,当我添加用于守护此答案中找到的应用程序的代码时。我遇到了一个小问题,使用fork()
将创建我整个正在运行的应用程序的副本,这就是fork()
. 所以,我想解决这个问题。
我的ProcessConnection()
长相是这样的
我将如何简单地在上面或之后添加几行connecting=socket = accept
......以使其同时接受多个连接?我可以使用fork();
但归结为DisposeCurrentConnection();
我想终止该进程并让父线程运行。
multithreading - POSIX 取消点是什么?
POSIX 取消点是什么?我正在寻找一份明确的 POSIX 取消点列表。
我之所以问,是因为我有一本书说accept()
是select()
取消点,但我看到互联网上的网站声称它们不是。
此外,如果 Linux 取消点与 POSIX 取消点不同,我也想要一份它们的列表。
c++ - 在静态初始化程序中使用 getenv() 是否安全,即在 main() 之前?
我查看了Stevens和Posix Programmer's Guide,我能找到的最好的是
当进程开始时,一个称为环境的字符串数组可用。该数组由外部变量 指向,
environ
定义为:
extern char **environ;
正是那个环境变量让我犹豫不决。我想说
- 调用进程/shell 已经分配了空终止字符串块
- 'external' 变量被getenv()environ
用作入口点。
- ipso facto可以随意在静态初始化程序中调用getenv() 。
但是我找不到任何保证environ的“静态初始化”在所有其他静态初始化代码之前。这是我想太多了吗?
更新
在我的平台(AMD Opteron、Redhat 4、GCC 3.2.3)上,设置LD_DEBUG表明在调用我的静态初始化程序之前设置了environ 。这是一件好事。谢谢,@codelogic。但这不一定是我在所有平台上都能得到的结果。
此外,虽然我直观地同意@ChrisW 关于 C/C++ 运行时库的行为,但这只是我基于经验的直觉。因此,任何可以从某个权威的地方引用来保证环境在调用静态初始化程序之前就在那里的人,加分!
c - 查明管道的读取端当前是否阻塞
我试图找出子进程是否正在等待用户输入(不解析其输出)。是否有可能在 Unix 上的 C 中确定管道的读取端当前是否有 read() 调用阻塞?
问题是,我无法控制子进程中执行的程序。他们打印出我通常希望重定向到 /dev/null 的各种冗长的垃圾。偶尔会提示用户一些东西。(提示没有可靠的格式。)所以我的想法是:
- 在一个循环中:
- 排空孩子的标准输出,将其附加到临时缓冲区。
- 检查(不知道如何)孩子是否要求用户输入,在这种情况下,缓冲区将打印到标准输出。
- 当孩子退出时,扔掉缓冲区。