.. SPDX-License-Identifier: GPL-2.0 .. include:: ../disclaimer-zh_CN.rst :Original: Documentation/userspace-api/futex2.rst :翻译: æŽç¿ Rui Li <me@lirui.org> ====== futex2 ====== :作者: André Almeida <andrealmeid@collabora.com> futex,或者称为快速用户互斥é”(fast user mutex),是一组å…许用户空间创建高性能åŒæ¥ 机制的系统调用,比如用户空间ä¸çš„互斥é”,信å·é‡å’Œæ¡ä»¶å˜é‡ã€‚Cæ ‡å‡†åº“ï¼Œå¦‚glibc,使用它作 为实现更多高级接å£çš„æ–¹å¼ï¼Œå¦‚pthreads。 futex2是åˆä»£futex系统调用的åŽç»ç‰ˆæœ¬ï¼Œæ—¨åœ¨å…‹æœåŽŸæœ‰æŽ¥å£çš„é™åˆ¶ã€‚ 用户API ======= ``futex_waitv()`` ----------------- ç‰å¾…一个futex数组,å¯ç”±å…¶ä¸ä»»æ„一个唤醒:: futex_waitv(struct futex_waitv *waiters, unsigned int nr_futexes, unsigned int flags, struct timespec *timeout, clockid_t clockid) struct futex_waitv { __u64 val; __u64 uaddr; __u32 flags; __u32 __reserved; }; 用户空间设置一个struct futex_waitv数组(最多128项),设置 ``uaddr`` 为ç‰å¾…çš„ 地å€ï¼Œ ``val`` 为期望值, ``flags`` 为指定的类型(如private)和futex的大å°ã€‚ ``__reserved`` 需è¦ç½®ä¸º0,但是它å¯ç”¨ä½œæœªæ¥æ‰©å±•ã€‚指å‘æ•°ç»„ç¬¬ä¸€ä¸ªå…ƒç´ çš„æŒ‡é’ˆä½œä¸º ``waiters`` ä¼ é€’ã€‚å¦‚æžœ ``waiters`` 或任何的 ``uaddr`` 地å€æ— 效,将返回 ``-EFAULT`` 。 如果用户空间拥有32ä½çš„指针,那么需è¦åšæ˜¾å¼è½¬æ¢æ¥ä¿è¯é«˜ä½æ¸…零。 ``uintptr_t`` 设计 得很精巧,在32/64ä½çš„指针上都æ£å¸¸å·¥ä½œã€‚ ``nr_futexes`` 指定了数组的大å°ã€‚ä¸åœ¨[1,128]区间内的值会使系统调用返回 ``-EINVAL`` 。 系统调用的 ``flags`` å‚数需è¦ç½®0,但å¯ç”¨ä½œæœªæ¥æ‰©å±•ã€‚ 对于æ¯ä¸ª ``waiters`` 数组ä¸çš„项,在 ``uaddr`` 的当å‰å€¼ä¼šå’Œ ``val`` 比较。如果 ä¸ä¸€è‡´ï¼Œç³»ç»Ÿè°ƒç”¨ä¼šæ’¤é”€æˆªè‡³ç›®å‰å®Œæˆçš„所有工作,并返回 ``-EAGAIN`` 。如果所有测试 和验è¯éƒ½é€šè¿‡ï¼Œç³»ç»Ÿè°ƒç”¨ä¼šç‰å¾…直到以下情况之一å‘生: - 指定的timeout超时,返回 ``-ETIMEOUT`` 。 - 一个信å·è¢«ä¼ 递给ç¡çœ ä¸çš„任务,返回 ``-ERESTARTSYS`` 。 - æŸä¸ªåˆ—表ä¸çš„futex被唤醒,返回那个被唤醒的futex的索引。 关于如何使用接å£çš„例åå¯ä»¥åœ¨ ``tools/testing/selftests/futex/functional/futex_waitv.c`` ä¸æ‰¾åˆ°ã€‚ 超时 ---- ``struct timespec *timeout`` 是一个指å‘ç»å¯¹è¶…时时间的å¯é€‰å‚æ•°ã€‚ä½ éœ€è¦åœ¨ ``clockid`` å‚æ•°ä¸æŒ‡å®šè¦ä½¿ç”¨çš„æ—¶é’Ÿç±»åž‹ã€‚æ”¯æŒ ``CLOCK_MONOTONIC`` å’Œ ``CLOCK_REALTIME`` 。这个 系统调用åªæŽ¥å—64ä½çš„timespec结构体。 futex的类型 ----------- futexæ—¢å¯ä»¥æ˜¯ç§æœ‰çš„也å¯ä»¥æ˜¯å…±äº«çš„。ç§æœ‰ç”¨äºŽå¤šä¸ªè¿›ç¨‹å…±äº«åŒæ ·çš„内å˜ç©ºé—´ï¼Œå¹¶ä¸”futex的虚拟 地å€å¯¹æ‰€æœ‰è¿›ç¨‹éƒ½æ˜¯ä¸€æ ·çš„。这å…è®¸åœ¨å†…æ ¸ä¸è¿›è¡Œä¼˜åŒ–。è¦ä½¿ç”¨ç§æœ‰futex,需è¦åœ¨futexæ ‡å¿—ä¸æŒ‡å®š ``FUTEX_PRIVATE_FLAG`` 。对于那些ä¸åœ¨åŒä¸€å†…å˜ç©ºé—´å…±äº«çš„进程,å¯ä»¥è®©åŒä¸€ä¸ªfutex拥有ä¸åŒ 的虚拟地å€ï¼ˆä¾‹å¦‚使用基于文件的共享内å˜ï¼‰ï¼Œè¿™éœ€è¦ä¸åŒçš„内部机制æ¥ä½¿å¾—æ£ç¡®è¿›å…¥é˜Ÿåˆ—。这是默认 的行为,而且对ç§æœ‰futex和共享futex都适用。 futexå¯ä»¥æ˜¯ä¸åŒçš„大å°ï¼š8,16,32或64ä½ã€‚ç›®å‰åªæ”¯æŒ32ä½å¤§å°çš„futex,并且需è¦é€šè¿‡ ``FUTEX_32`` æ ‡å¿—æŒ‡å®šã€‚