一般来说,线程同步原语使得用户空间程序必须使用系统调用。系统调用对于将一个线程置于睡眠状态并等待另一个线程或将一个线程从睡眠中唤醒来说,本来就是不可避免的。例如,获得一个未被满足的锁,并没有必要进行系统调用,至少自然不会。futex是对这一挑战的补救措施。futex是一个简单的瞬时整数地址。该地址用于识别等待处理的线程队列。该位置的整数值被用来执行快速路径的原子操作(如果有的话),以及处理冲突情况下的角逐情况。futex()系统调用允许程序等待某一特定地址的值发生变化,并唤醒在该地址上等待的任何人。它最常用于实现futex(7)中提到的共享内存锁这种有争议的情况。当用户空间的futex(7)动作不能无误完成时,需要调用内核来解决这个问题。仲裁可以用来使调用的进程进入睡眠状态或唤醒等待的进程。在futex中定义的语义被期望被这个函数的调用者所遵循(7)。
由于这些语义需要编写非可移植的汇编指令,大多数用户很可能是库的作者,而不是普通的应用开发者。Futex是一个单一的系统调用,执行许多操作。这可能显得很奇怪,甚至令人困惑,如果不是彻头彻尾的话。然而,对于一个独一无二的系统调用来说,这是标准的程序:"ioctl "系统调用包含的操作比Futex多得多。对于另一个例子,程序员不太可能发现,因为Glibc隐藏了它,尽管单一的套接字调用系统实现了所有与套接字有关的功能。因此,如果线程在单个进程中访问它,它可以被指定为一个全局变量,或者如果来自不同进程的线程利用它,它可以存储在一个共享内存段中。在用户空间使用原子操作更新的状态被存储在共享变量中。当状态显示没有冲突时,就不需要系统调用了。如果状态显示有冲突,在另一边,会进行futex系统调用,使调用任务进入睡眠状态。
用C语言解释futex()系统调用的例子
为了理解C语言中的futex()系统调用,我们安装了Ubuntu 20.04 Linux操作系统。创建一个名为 "fc.c "的文件。该文件的标题可以修改,但扩展名将保持不变。因此,首先在 "应用程序 "中找到已安装的Ubuntu 20.04 Linux操作系统的外壳,或检查 "Ctrl+Alt+T "键,打开它。一旦打开,在已安装的Ubuntu 20.04 Linux操作系统的终端上运行所附指令。
$ nano fc.c

只有当你的屏幕上出现GNU nano编辑器时,你才能确认该文件的成功执行。现在你必须写出所附截图中显示的代码。这是futex()系统调用的一个最基本的例子。

< STDIO.H >是一个包含各种函数和宏的声明的文件,这些函数和宏需要从输入端接收输入并在C程序的输出窗口显示输出。没有必要添加 "stdio.h",因为我们可以使用任何其他程序,如DOS,向c程序提供输入,并存储结果。<unistd. h>头提供并声明了各种符号常量和类型,以及各种函数。syscall()是一个很小的库函数,它用要求的参数量和给定的汇编语言接口调用系统调用。一旦你理解了上述显示的代码,你就可以检查输出了。我们已经安装了一个GCC编译器来编译代码。GNU C编译器,或称GCC,是以C语言为编程语言的程序员中最著名和广泛使用的编译器。GCC是一个可以使用的编译器,所有Linux发行版都是免费的。现在在Ubuntu 20.04 Linux系统的终端上执行后面的命令。
$ gcc fc.c
$ ./a.out

输出结果可以在上面的图片中看到。
总结
本文简要介绍了C语言编程中的futex()系统调用。我们有一个简单而简要的futex()系统调用的例子。实现同样的例子并增加一些小的变化,可以帮助你理解C语言中的futex()系统调用。