gpt4 book ai didi

fnctl(F_SETOWN, ) 能否将信号定向到 pthread ID 而不是进程 ID?

转载 作者:太空狗 更新时间:2023-10-29 12:09:22 26 4
gpt4 key购买 nike

我正在开发一个应用程序,它将在 Linux 上从串口/UART 读取数据。当 UART 从外部源异步获取可用数据时,我正在尝试唤醒/取消阻止 pthread 开始读取数据。我正在考虑使用信号 (SIGIO)“软中断”而不是 select() 或 pselect(),但我不确定我能否在多线程应用程序中从信号中获得我想要的行为。

当我配置设备文件描述符时,我想设置 F_SETOWN(int) 以使内核向我设置为在 SIGIO 上阻塞的 pthread 发送信号。

            // Configure the signal to send
fcntl(m_fileId, F_SETSIG, m_sigNum);

// Set to non-blocking read mode
fcntl(m_fileId, F_SETFL, FNDELAY);

// Bind the PID of the task which is getting the signal
fcntl(m_fileId, F_SETOWN, m_pid);

// Enable sending a signal when data ready
fcntl(m_fileId, F_SETFL, O_ASYNC);

我意识到,当我编写代码时,m_pid 被设置为进程 ID,而不是 pthread ID,而且当我查看手册页时...

根据 fnctl(2) 手册页:

F_SETOWN (int)

Set the process ID or process group ID that will receive SIGIO and SIGURG signals for events on file descriptor fd to the ID given in arg. A process ID is specified as a positive value; a process group ID is specified as a negative value. Most commonly, the calling process specifies itself as the owner (that is, arg is specified as getpid(2)).

除了对进程 ID 使用 getpid() 之外,您是否可以通过调用 pthread_self() 传入 pthread ID,以便只有特定线程获得信号?

最佳答案

在 Linux 上,您可以使用 F_SETOWN_EX 来定位特定线程。

来自手册页:

The following was true in 2.6.x kernels up to and including kernel 2.6.11:

If a nonzero value is given to F_SETSIG in a multithreaded process running with a threading library that sup‐ ports thread groups (e.g., NPTL), then a positive value given to F_SETOWN has a different meaning: instead of being a process ID identifying a whole process, it is a thread ID identifying a specific thread within a process. Consequently, it may be necessary to pass F_SETOWN the result of gettid(2) instead of getpid(2) to get sensible results when F_SETSIG is used. (In current Linux threading implementations, a main thread's thread ID is the same as its process ID. This means that a single-threaded program can equally use gettid(2) or getpid(2) in this scenario.) Note, however, that the statements in this paragraph do not apply to the SIGURG signal generated for out-of-band data on a socket: this signal is always sent to either a process or a process group, depending on the value given to F_SETOWN.

The above behavior was accidentally dropped in Linux 2.6.12, and won't be restored. From Linux 2.6.32 onward, use F_SETOWN_EX to target SIGIO and SIGURG signals at a particular thread.

Linux 将期望一个 pid/tid(从内核的角度来看线程 ID;Linux 通常称它们为 pid,尽管它们标识的是线程而不是进程),但不是 pthread_t.

Pthread 实现通常会在内部以特定于实现的方式将 pthread_t 映射到 pids,您可以破解您的特定实现来获取它。

或者,您可以包装 pthread_create 以在线程创建时插入一个 pthread_t-to-pid 映射哈希表条目,以便您稍后可以将 pthread_t 映射到 pid 不依赖于您的 pthread 实现。

(您可以使用syscall(SYS_gettid) 获取当前线程的pid)。

关于fnctl(F_SETOWN, <pid>) 能否将信号定向到 pthread ID 而不是进程 ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52557115/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com