【C语言】sem_timedwait

192 篇文章 3 订阅
187 篇文章 1 订阅
文章介绍了C语言中的sem_timedwait函数,它是POSIX标准中用于线程同步的信号量操作,允许有时间限制地等待信号量变为非零。函数原型包括信号量指针和绝对超时时间,适用于多线程环境下管理共享资源访问。
摘要由CSDN通过智能技术生成

   sem_timedwait 是 POSIX(便携式操作系统接口)标准定义的一个同步原语,用于线程或进程同步中的信号量操作。在涉及多线程编程时,信号量(semaphore)是用来控制对共享资源或临界区域访问的一种机制。

   sem_timedwait函数对信号量执行减操作(通常称为wait 或 P 操作),如果信号量的值大于0,那么该函数将信号量的值减1并立即返回;如果信号量的值为0,则调用线程将被阻塞。不同于`sem_wait`函数,`sem_timedwait`允许你设置一个超时时间——这意味着如果指定的时间内信号量没有被释放(即其值不变为大于0),调用线程会在超时后停止阻塞,这时函数返回-1,并设置errno为ETIMEDOUT,表示已经超时。

可以理解为:
sem 是信号量的缩写。
timed 表示这个操作是有时间限制的。
wait 表示调用此函数的线程将等待(可能阻塞)直到信号量的值变为非零。

函数的原型:

int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

参数和返回值:

sem 是指向信号量对象的指针。
abs_timeout 指定了一个绝对超时时间,一旦达到这个时间,如果信号量依然没有被释放(即依然为0),则函数会因超时而返回。

函数返回值:
- 如果成功,`sem_timedwait` 函数返回0。
- 如果在指定时间内信号量没有被释放,`sem_timedwait`将返回-1,并设置errno为ETIMEDOUT。

sem_timedwait是一个有用的工具,可以用来在多线程环境中同步对共享资源的访问,同时提供了超时机制,以避免无限期的等待。 

示例代码:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>

sem_t sem;

void* worker_thread(void* arg) {
    // 设置超时时间为2秒后
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    ts.tv_sec += 2;

    printf("Thread attempting to acquire the semaphore...\n");
    // 尝试获取信号量,最多等待2秒
    if (sem_timedwait(&sem, &ts) == -1) {
        perror("sem_timedwait");
        printf("Could not acquire semaphore within 2 seconds.\n");
    } else {
        // 成功获取信号量
        printf("Semaphore acquired by thread.\n");
        // 释放信号量
        sem_post(&sem);
    }
    return NULL;
}

int main() {
    pthread_t tid;
    
    // 初始化信号量,初始值为0
    sem_init(&sem, 0, 0);

    // 创建线程
    pthread_create(&tid, NULL, worker_thread, NULL);

    // 等待一段时间,例如1秒
    sleep(1);

    // 释放信号量
    printf("Main thread signals semaphore.\n");
    sem_post(&sem);

    // 等待线程完成
    pthread_join(tid, NULL);

    // 销毁信号量
    sem_destroy(&sem);

    return 0;
}

        在上面的代码示例中,创建了一个线程,该线程尝试使用 sem_timedwait 函数获取一个信号量。超时时间设置为当前时间后的2秒。主线程休眠1秒后发出信号,从而释放信号量。子线程获取信号量后,会释放它。如果子线程在超时之前无法获取信号量,则会打印错误消息。 

ChatGPT

在C语言中,`sem_timedwait()` 是 POSIX 信号量库中的一个函数,它用于等待信号量变为非零值,即等待资源可用。当资源可用时,它会自动将信号量值减一。如果在指定的超时时间内信号量没有变为可用状态,函数会失败并返回 -1,并设置 errno 为 ETIMEDOUT。
这是 sem_timedwait() 函数的原型:

#include <semaphore.h>
#include <time.h>

int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

参数说明:
- sem: 指向信号量对象的指针。
- abs_timeout: 指向 timespec 结构的指针,它定义了一个绝对超时时间。超时时间通常是从 UTC 1970-01-01 00:00:00 +0000 (Epoch) 开始计算的秒数和纳秒数。
返回值:
- 成功时,函数返回 0。
- 如果在超时时间内信号量没有变为可用状态,返回 -1,并设置 errno 为 ETIMEDOUT。
- 如果有其他错误发生,函数同样返回 -1 并设置 errno 为相应的错误码。
使用例子:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <semaphore.h>
#include <time.h>

int main() {
    sem_t sem;
    if (sem_init(&sem, 0, 0) == -1) { // 初始化信号量,初始值为 0
        perror("sem_init");
        exit(EXIT_FAILURE);
    }

    struct timespec ts;
    if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
        perror("clock_gettime");
        exit(EXIT_FAILURE);
    }

    ts.tv_sec += 10; // 设定超时时间为当前时间后 10 秒

    int res = sem_timedwait(&sem, &ts);
    if (res == -1) {
        if (errno == ETIMEDOUT) {
            printf("sem_timedwait timed out\n");
        } else {
            perror("sem_timedwait");
        }
        exit(EXIT_FAILURE);
    } else {
        printf("sem_timedwait succeeded\n");
    }

    if (sem_destroy(&sem) == -1) {
        perror("sem_destroy");
    }

    return 0;
}

在这个例子中,我们初始化了一个信号量 sem,其初始值为 0。我们设定一个超时时间,从当前时间开始加上 10 秒。之后调用 sem_timedwait() 尝试等待信号量增加。如果在指定的超时时间内,没有其他线程或进程通过 sem_post() 增加信号量,`sem_timedwait()` 将会超时返回。如果信号量在超时之前变为可用状态,`sem_timedwait()` 会减少信号量的值并成功返回。

请注意,`sem_timedwait()` 并不是所有系统上都可用,它依赖于系统提供 POSIX 计时器和信号量的支持。在使用之前,你应该检查你的系统是否支持该函数以及相关的头文件和库。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

109702008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值