Enabling/disabling Unix串行编程中的位意义

Enabling/disabling bitwise meaning in Unix serial programming

我正在学习 Unix 串行编程,我注意到按位运算符的两种用法如下:

tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
tty.c_cflag |= CRTSCTS;  // Enable RTS/CTS hardware flow control

&= 和 ~ 的任何出现表示禁用,|= 表示启用功能。在处理标志和按位运算时,这是 enabling/disabling 功能的一些通用约定吗?换句话说,这些按位运算的用途是否专门用于此目的?或者在这背后有一个 Unix 使用的掩码,它与其他所有库都不同?例如我可以使用 |= 来禁用而不是启用功能。

在 setting/clearing 位数组之后,库如何检查设置了哪些功能并相应地调用事件?它是否对每一位都使用 if 语句?我正在尝试构建类似的东西,我想知道在用户通过他想要的功能后使用 if 语句是否有效?

如果你想从同一个运算符启用和禁用,只需使用 ^=(XOR) 而不是 |= 并且 |= 不能禁用,因为它分配 1如果其中一位是 1 那么它就不能禁用

I'm learning about Unix serial programming

明确地说,您似乎指的是串行终端的 POSIX 接口,又名 termios。注意这里API结合了串口和串口终端的配置
另请注意,termios 属性的位值取决于特定的 OS 和 CPU 体系结构。


I have noticed two uses of bitwise operators ...

正式名称为 Boolean arithmetic

参考Setting Terminal Modes Properly使用termios属性的按位运算的原因。

When you set terminal modes, you should call tcgetattr() first to get the current modes of the particular terminal device, modify only those modes that you are really interested in, and store the result with tcsetattr().

... you should start with the current value of the member and alter only the flags whose values matter in your program, leaving any other flags unchanged.


any appearance of &= and ~ means disabling and |= means enabling a feature. Is this some universal convention for enabling/disabling features when dealing with flags and bitwise operations?

某种程度上,无论如何都是为了软件。
请注意,您将布尔值和算术与特征以及 enabling/disabling 它们混为一谈。
对于 termios(和典型的 API),二进制 1 等同于条件 the feature is enabled.
然而,某些接口,尤其是硬件接口,可能会使用反向逻辑,其中 1 表示取消断言或 false.
例如,大多数 RS-232 调制解调器控制和握手信号使用反逻辑。


in other words, are those uses of bitwise operations used specifically for this purpose?

“目的”是为了设置and/or明确而已结构成员中的位(不修改其他 bits/sflags),它将与 OS 通信您的程序想要使用的终端和通信设置(当您的程序使用 传递 termios 结构时tcsetattr() 系统调用).

一般来说,您的程序不会知道预先存在的 termios 配置,也不应该关心。因此,最佳做法(对于 robustness/portability)是让您的程序根据需要启用 and/or 禁用 all attributes/flags(使用按位运算)。


or there's a mask behind this that Unix uses and it's different with every other library?

“面具”?

Termios 是一个 API(即与 OS 子系统交互的应用程序接口),而不是 “库”(即与您的应用程序链接的例程)。

你问的是 XY 问题吗?


I can use |= for disabling instead of enabling features.

使用 1 位的布尔 OR 运算将始终导致置位。
因此,如果设置位意味着启用该功能(这对于 termios API 是典型的),那么答案是“不,这不会禁用功能”。
如果使用反逻辑,答案可能是肯定的。

Is this some universal convention for enabling/disabling features when dealing with flags and bitwise operations?

是的。通常,|= x 设置一个或多个位,&= ~x 清除一个或多个位。

然而,~ 运算符是有问题的,因为它带有内置的整数提升,因此您经常会发现这样的代码更适合写成 &= (uint8_t)~x 等,其中 uint8_t是预期的类型。

同样,C 库 API 期望用户提供多个按位 OR:ed 位标志作为输入是相当普遍的。例如:func(GIMME_THIS | GIMME_THAT);.


After setting/clearing the bit array, how does the library check which features were set and call events accordingly? does it use if-statements for each bit?
I wonder if using if-statements is efficient

很有可能,是的。它内存效率高,因为它节省了一些内存来将相关的位标志组合在同一个位字段中,而不是将它们存储为单独的变量。

否则,如果您正在寻找执行速度效率,那么使用不同的变量通常更有效,至少在中高端 CPU 上 - 32 位或更大。由于这些 CPU 有对齐要求并且更喜欢使用 32 位块。

但我们在这里谈论的是手动微优化 - 手动代码优化是一项技术性工作,需要对特定目标有很多了解。因此,初学者和中级熟练的程序员通常不需要担心。而是专注于编写 可读 代码,让编译器担心优化。事实证明,可读代码通常也会产生高效代码。