菜单

Cobalt/Condition variable services

POSIX风格的条件变量机制。


详细描述

条件变量是一种同步机制,允许任务挂起执行,直到满足对某些任意共享数据的某种谓词。

对条件的基本操作是:信号条件(当谓词变为真时),以及等待条件,阻塞任务执行,直到另一个任务信号条件。条件变量必须始终与互斥量关联,以避免一种众所周知的竞态条件,即一个任务准备等待条件变量,另一个任务在第一个任务实际等待它之前就信号条件。


函数文档

rt_cond_bind

int rt_cond_bind (RT_COND *cond, const char *name, RTIME timeout);

绑定到一个条件变量。

此例程创建一个新的描述符,以引用由其符号名标识的现有条件变量。如果对象在入口处不存在,调用者可能会阻塞,直到创建了给定名称的条件变量。

参数

  • cond 由操作填充的条件变量描述符的地址。失败时,此内存的内容未定义。
  • name 一个有效的以NULL结尾的名字,用于标识要绑定的条件变量。此字符串应与传递给 rt_cond_create() 的对象名参数匹配。
  • timeout 等待注册发生的时钟滴答数(见注意)。传递 TM_INFINITE 会导致调用者无限期阻塞,直到对象被注册。传递 TM_NONBLOCK 会导致服务在对象在入口处未注册时立即返回,而不等待。

返回值

成功时返回零。否则:

  • 如果在检索完成之前为当前任务调用了 rt_task_unblock(),则返回 -EINTR。
  • 如果 timeout 等于 TM_NONBLOCK 并且在入口处未注册搜索的对象,则返回 -EWOULDBLOCK。
  • 如果无法在指定的时间内检索到对象,则返回 -ETIMEDOUT。
  • 如果此服务应阻塞,但未从 Xenomai 线程调用,则返回 -EPERM。

标签

xthread-nowait, switch-primary

注意

超时值被解释为 Alchemy 时钟分辨率的倍数(参见 alchemy-clock-resolution 选项,默认为1纳秒)。

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/mutex.h>
#include <alchemy/cond.h>

#define TASK_STACK_SIZE 0  // 使用默认栈大小
#define TASK_PRIORITY 50   // 中等优先级

RT_TASK producer_task, consumer_task, another_task;
RT_MUTEX mutex;
RT_COND cond;

int shared_data = 0;
int data_ready = 0;
int data_ready_another = 0;

void producer(void *arg)
{ 
    rt_task_sleep(1000000000);  // 睡眠1秒
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        shared_data++;
        printf("Producer: produced data %d\n", shared_data);
        data_ready = 1;
        data_ready_another = 1;
        
        rt_cond_broadcast(&cond);
        rt_mutex_release(&mutex);
        
       rt_task_sleep(1000000000);  // 睡眠1秒
    }
}

void consumer(void *arg)
{
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        while (!data_ready) {
            rt_cond_wait(&cond, &mutex, TM_INFINITE);
        }
        
        printf("Consumer: consumed data %d\n", shared_data);
        data_ready = 0;
        rt_mutex_release(&mutex);
    }
}

void another_consumer(void *arg)
{
    RT_COND cond_bind;
    int ret = rt_cond_bind(&cond_bind, "example_cond",TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        return;
    }
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        while (!data_ready_another) {
            rt_cond_wait(&cond_bind, &mutex, TM_INFINITE);
        }

        printf("Another_Consumer: consumed data %d\n", shared_data);
        data_ready_another = 0;
        rt_mutex_release(&mutex);
    }
    rt_cond_unbind(&cond_bind);
}

int main(int argc, char *argv[])
{
    int ret;

    // 创建互斥锁
    ret = rt_mutex_create(&mutex, "example_mutex");
    if (ret) {
        fprintf(stderr, "Failed to create mutex: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    // 创建条件变量
    ret = rt_cond_create(&cond, "example_cond");
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建生产者任务
    ret = rt_task_create(&producer_task, "producer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create producer task: %s\n", strerror(-ret));
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建消费者任务
    ret = rt_task_create(&consumer_task, "consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }
    // 创建另一个消费者任务
    ret = rt_task_create(&another_task, "another_consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&consumer_task);
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }


    // 启动任务
    rt_task_start(&producer_task, &producer, NULL);
    rt_task_start(&consumer_task, &consumer, NULL);
    rt_task_start(&another_task, &another_consumer, NULL);

    rt_task_join(&producer_task);
    rt_task_join(&consumer_task);
    rt_task_join(&another_task);
    rt_cond_delete(&cond);
    rt_mutex_delete(&mutex);

    return EXIT_SUCCESS;
}

rt_cond_broadcast

int rt_cond_broadcast (RT_COND *cond);

广播一个条件变量。

所有当前等待条件变量的任务都会立即解除阻塞。

参数

  • cond 条件变量描述符。

返回值

成功时返回零。否则:

  • 如果 cond 不是有效的条件变量描述符,则返回 -EINVAL。

标签

unrestricted, switch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/mutex.h>
#include <alchemy/cond.h>

#define TASK_STACK_SIZE 0  // 使用默认栈大小
#define TASK_PRIORITY 50   // 中等优先级

RT_TASK producer_task, consumer_task, another_task;
RT_MUTEX mutex;
RT_COND cond;

int shared_data = 0;
int data_ready = 0;
int data_ready_another = 0;

void producer(void *arg)
{ 
    rt_task_sleep(1000000000);  // 睡眠1秒
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        shared_data++;
        printf("Producer: produced data %d\n", shared_data);
        data_ready = 1;
        data_ready_another = 1;
        
        rt_cond_broadcast(&cond);
        rt_mutex_release(&mutex);
        
       rt_task_sleep(1000000000);  // 睡眠1秒
    }
}

void consumer(void *arg)
{
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        while (!data_ready) {
            rt_cond_wait(&cond, &mutex, TM_INFINITE);
        }
        
        printf("Consumer: consumed data %d\n", shared_data);
        data_ready = 0;
        rt_mutex_release(&mutex);
    }
}

void another_consumer(void *arg)
{
    RT_COND cond_bind;
    int ret = rt_cond_bind(&cond_bind, "example_cond",TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        return;
    }
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        while (!data_ready_another) {
            rt_cond_wait(&cond_bind, &mutex, TM_INFINITE);
        }

        printf("Another_Consumer: consumed data %d\n", shared_data);
        data_ready_another = 0;
        rt_mutex_release(&mutex);
    }
    rt_cond_unbind(&cond_bind);
}

int main(int argc, char *argv[])
{
    int ret;

    // 创建互斥锁
    ret = rt_mutex_create(&mutex, "example_mutex");
    if (ret) {
        fprintf(stderr, "Failed to create mutex: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    // 创建条件变量
    ret = rt_cond_create(&cond, "example_cond");
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建生产者任务
    ret = rt_task_create(&producer_task, "producer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create producer task: %s\n", strerror(-ret));
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建消费者任务
    ret = rt_task_create(&consumer_task, "consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }
    // 创建另一个消费者任务
    ret = rt_task_create(&another_task, "another_consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&consumer_task);
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }


    // 启动任务
    rt_task_start(&producer_task, &producer, NULL);
    rt_task_start(&consumer_task, &consumer, NULL);
    rt_task_start(&another_task, &another_consumer, NULL);

    rt_task_join(&producer_task);
    rt_task_join(&consumer_task);
    rt_task_join(&another_task);
    rt_cond_delete(&cond);
    rt_mutex_delete(&mutex);

    return EXIT_SUCCESS;
}

rt_cond_create

int rt_cond_create (RT_COND *cond, const char *name);

创建一个条件变量。

创建一个同步对象,允许任务挂起执行,直到满足对某些共享数据的某种谓词。

参数

  • cond 一个条件变量描述符的地址,如果此调用成功,可以稍后用于唯一地标识创建的对象。
  • name 一个ASCII字符串,代表条件变量的符号名称。当非NULL且非空时,此字符串的副本用于将创建的条件变量索引到对象注册表。

返回值

成功时返回零。否则:

  • 如果系统无法从主堆获取内存以创建条件变量,则返回 -ENOMEM。
  • 如果名称与已注册的条件变量冲突,则返回 -EEXIST。
  • 如果此服务是从无效的上下文调用的,例如中断或非Xenomai线程,则返回 -EPERM。

注意

超时值被解释为 Alchemy 时钟分辨率的倍数(参见 alchemy-clock-resolution 选项,默认为1纳秒)。

注意

如果底层线程库不支持 pthread_condattr_setclock(),则使用 Alchemy 条件变量的计时将基于 CLOCK_REALTIME,并因此可能受到系统日期更新(例如 NTP)的影响。这通常涉及基于 linuxthreads 库的旧版设置。在正常情况下,计时基于 CLOCK_MONOTONIC。

标签

xthread-only, mode-unrestricted, switch-secondary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/mutex.h>
#include <alchemy/cond.h>

#define TASK_STACK_SIZE 0  // 使用默认栈大小
#define TASK_PRIORITY 50   // 中等优先级

RT_TASK producer_task, consumer_task;
RT_MUTEX mutex;
RT_COND cond;

int shared_data = 0;
int data_ready = 0;

void producer(void *arg)
{
    rt_task_sleep(1000000000);  // 睡眠1秒
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        shared_data++;
        printf("Producer: produced data %d\n", shared_data);
        data_ready = 1;
        
        rt_cond_signal(&cond);
        rt_mutex_release(&mutex);
        
        rt_task_sleep(1000000000);  // 睡眠1秒
    }
}

void consumer(void *arg)
{
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        while (!data_ready) {
            rt_cond_wait(&cond, &mutex, TM_INFINITE);
        }
        
        printf("Consumer: consumed data %d\n", shared_data);
        data_ready = 0;
        rt_mutex_release(&mutex);   
    }
}

int main(int argc, char *argv[])
{
    int ret;

    // 创建互斥锁
    ret = rt_mutex_create(&mutex, "example_mutex");
    if (ret) {
        fprintf(stderr, "Failed to create mutex: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    // 创建条件变量
    ret = rt_cond_create(&cond, "example_cond");
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建生产者任务
    ret = rt_task_create(&producer_task, "producer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create producer task: %s\n", strerror(-ret));
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建消费者任务
    ret = rt_task_create(&consumer_task, "consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&producer_task, &producer, NULL);
    rt_task_start(&consumer_task, &consumer, NULL);

    rt_task_join(&producer_task);
    rt_task_join(&consumer_task);
    rt_cond_delete(&cond);
    rt_mutex_delete(&mutex);

    return EXIT_SUCCESS;
}

rt_cond_delete

int rt_cond_delete (RT_COND *cond);

删除一个条件变量。

此例程删除由 rt_cond_create() 调用先前创建的条件变量对象。

参数

  • cond 条件变量描述符。

返回值

成功时返回零。否则:

  • 如果 cond 不是有效的条件变量描述符,则返回 -EINVAL。
  • 如果此服务是从异步上下文调用的,则返回 -EPERM。
  • 如果在引用 cond 的对象(例如,当它在另一个任务的 rt_cond_wait(),rt_cond_wait_timed() 或 rt_cond_wait_until() 中使用时)被尝试销毁,则返回 -EBUSY。

标签

mode-unrestricted, switch-secondary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/mutex.h>
#include <alchemy/cond.h>

#define TASK_STACK_SIZE 0  // 使用默认栈大小
#define TASK_PRIORITY 50   // 中等优先级

RT_TASK producer_task, consumer_task;
RT_MUTEX mutex;
RT_COND cond;

int shared_data = 0;
int data_ready = 0;

void producer(void *arg)
{
    rt_task_sleep(1000000000);  // 睡眠1秒
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        shared_data++;
        printf("Producer: produced data %d\n", shared_data);
        data_ready = 1;
        
        rt_cond_signal(&cond);
        rt_mutex_release(&mutex);
        
        rt_task_sleep(1000000000);  // 睡眠1秒
    }
}

void consumer(void *arg)
{
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        while (!data_ready) {
            rt_cond_wait(&cond, &mutex, TM_INFINITE);
        }
        
        printf("Consumer: consumed data %d\n", shared_data);
        data_ready = 0;
        rt_mutex_release(&mutex);   
    }
}

int main(int argc, char *argv[])
{
    int ret;

    // 创建互斥锁
    ret = rt_mutex_create(&mutex, "example_mutex");
    if (ret) {
        fprintf(stderr, "Failed to create mutex: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    // 创建条件变量
    ret = rt_cond_create(&cond, "example_cond");
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建生产者任务
    ret = rt_task_create(&producer_task, "producer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create producer task: %s\n", strerror(-ret));
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建消费者任务
    ret = rt_task_create(&consumer_task, "consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&producer_task, &producer, NULL);
    rt_task_start(&consumer_task, &consumer, NULL);

    rt_task_join(&producer_task);
    rt_task_join(&consumer_task);
    rt_cond_delete(&cond);
    rt_mutex_delete(&mutex);

    return EXIT_SUCCESS;
}

rt_cond_inquire

int rt_cond_inquire (RT_COND *cond, RT_COND_INFO *info);

查询条件变量状态。

此例程返回指定条件变量的状态信息。

参数

  • cond 条件变量描述符。
  • info 一个指向返回缓冲区的指针,用于复制信息。

返回值

成功时返回零,并将状态信息写入由 info 指向的结构。否则:

  • 如果 cond 不是有效的条件变量描述符,则返回 -EINVAL。

标签

unrestricted, switch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/mutex.h>
#include <alchemy/cond.h>

#define TASK_STACK_SIZE 0  // 使用默认栈大小
#define TASK_PRIORITY 50   // 中等优先级

RT_TASK producer_task, consumer_task;
RT_MUTEX mutex;
RT_COND cond;

int shared_data = 0;
int data_ready = 0;

void producer(void *arg)
{
    RT_COND_INFO info;
    int ret = rt_cond_inquire(&cond,&info);
    if(ret!=0)
    {
        fprintf(stderr, "Failed to get cond inquire: %s\n", strerror(-ret));
    }else{
        printf("Current Cond Name = %s\n",info.name);
    }

    rt_task_sleep(1000000000);  // 睡眠1秒 
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        shared_data++;
        printf("Producer: produced data %d\n", shared_data);
        data_ready = 1;
        
        rt_cond_signal(&cond);
        rt_mutex_release(&mutex);
        
        rt_task_sleep(1000000000);  // 睡眠1秒
    }
}

void consumer(void *arg)
{
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        while (!data_ready) {
            rt_cond_wait(&cond, &mutex, TM_INFINITE);
        }
        
        printf("Consumer: consumed data %d\n", shared_data);
        data_ready = 0;
        rt_mutex_release(&mutex);   
    }
}

int main(int argc, char *argv[])
{
    int ret;

    // 创建互斥锁
    ret = rt_mutex_create(&mutex, "example_mutex");
    if (ret) {
        fprintf(stderr, "Failed to create mutex: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    // 创建条件变量
    ret = rt_cond_create(&cond, "example_cond");
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建生产者任务
    ret = rt_task_create(&producer_task, "producer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create producer task: %s\n", strerror(-ret));
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建消费者任务
    ret = rt_task_create(&consumer_task, "consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&producer_task, &producer, NULL);
    rt_task_start(&consumer_task, &consumer, NULL);

    rt_task_join(&producer_task);
    rt_task_join(&consumer_task);
    rt_cond_delete(&cond);
    rt_mutex_delete(&mutex);

    return EXIT_SUCCESS;
}

rt_cond_signal

int rt_cond_signal (RT_COND *cond);

发出条件变量信号。

如果条件变量 cond 处于挂起状态,此例程立即解除阻塞第一个等待任务(按队列优先级顺序)。

参数

  • cond 条件变量描述符。

返回值

成功时返回零。否则:

  • 如果 cond 不是有效的条件变量描述符,则返回 -EINVAL。

标签

unrestricted, switch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/mutex.h>
#include <alchemy/cond.h>

#define TASK_STACK_SIZE 0  // 使用默认栈大小
#define TASK_PRIORITY 50   // 中等优先级

RT_TASK producer_task, consumer_task;
RT_MUTEX mutex;
RT_COND cond;

int shared_data = 0;
int data_ready = 0;

void producer(void *arg)
{
    rt_task_sleep(1000000000);  // 睡眠1秒
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        shared_data++;
        printf("Producer: produced data %d\n", shared_data);
        data_ready = 1;
        
        rt_cond_signal(&cond);
        rt_mutex_release(&mutex);
        
        rt_task_sleep(1000000000);  // 睡眠1秒
    }
}

void consumer(void *arg)
{
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        while (!data_ready) {
            rt_cond_wait(&cond, &mutex, TM_INFINITE);
        }
        
        printf("Consumer: consumed data %d\n", shared_data);
        data_ready = 0;
        rt_mutex_release(&mutex);   
    }
}

int main(int argc, char *argv[])
{
    int ret;

    // 创建互斥锁
    ret = rt_mutex_create(&mutex, "example_mutex");
    if (ret) {
        fprintf(stderr, "Failed to create mutex: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    // 创建条件变量
    ret = rt_cond_create(&cond, "example_cond");
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建生产者任务
    ret = rt_task_create(&producer_task, "producer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create producer task: %s\n", strerror(-ret));
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建消费者任务
    ret = rt_task_create(&consumer_task, "consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&producer_task, &producer, NULL);
    rt_task_start(&consumer_task, &consumer, NULL);

    rt_task_join(&producer_task);
    rt_task_join(&consumer_task);
    rt_cond_delete(&cond);
    rt_mutex_delete(&mutex);

    return EXIT_SUCCESS;
}

rt_cond_unbind

int rt_cond_unbind (RT_COND *cond);

从条件变量解除绑定。

参数

  • cond 条件变量描述符。

标签

thread-unrestricted

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/mutex.h>
#include <alchemy/cond.h>

#define TASK_STACK_SIZE 0  // 使用默认栈大小
#define TASK_PRIORITY 50   // 中等优先级

RT_TASK producer_task, consumer_task, another_task;
RT_MUTEX mutex;
RT_COND cond;

int shared_data = 0;
int data_ready = 0;
int data_ready_another = 0;

void producer(void *arg)
{ 
    rt_task_sleep(1000000000);  // 睡眠1秒
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        shared_data++;
        printf("Producer: produced data %d\n", shared_data);
        data_ready = 1;
        data_ready_another = 1;
        
        rt_cond_broadcast(&cond);
        rt_mutex_release(&mutex);
        
       rt_task_sleep(1000000000);  // 睡眠1秒
    }
}

void consumer(void *arg)
{
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        while (!data_ready) {
            rt_cond_wait(&cond, &mutex, TM_INFINITE);
        }
        
        printf("Consumer: consumed data %d\n", shared_data);
        data_ready = 0;
        rt_mutex_release(&mutex);
    }
}

void another_consumer(void *arg)
{
    RT_COND cond_bind;
    int ret = rt_cond_bind(&cond_bind, "example_cond",TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        return;
    }
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        while (!data_ready_another) {
            rt_cond_wait(&cond_bind, &mutex, TM_INFINITE);
        }

        printf("Another_Consumer: consumed data %d\n", shared_data);
        data_ready_another = 0;
        rt_mutex_release(&mutex);
    }
    rt_cond_unbind(&cond_bind);
}

int main(int argc, char *argv[])
{
    int ret;

    // 创建互斥锁
    ret = rt_mutex_create(&mutex, "example_mutex");
    if (ret) {
        fprintf(stderr, "Failed to create mutex: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    // 创建条件变量
    ret = rt_cond_create(&cond, "example_cond");
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建生产者任务
    ret = rt_task_create(&producer_task, "producer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create producer task: %s\n", strerror(-ret));
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建消费者任务
    ret = rt_task_create(&consumer_task, "consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }
    // 创建另一个消费者任务
    ret = rt_task_create(&another_task, "another_consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&consumer_task);
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }


    // 启动任务
    rt_task_start(&producer_task, &producer, NULL);
    rt_task_start(&consumer_task, &consumer, NULL);
    rt_task_start(&another_task, &another_consumer, NULL);

    rt_task_join(&producer_task);
    rt_task_join(&consumer_task);
    rt_task_join(&another_task);
    rt_cond_delete(&cond);
    rt_mutex_delete(&mutex);

    return EXIT_SUCCESS;
}

rt_cond_wait

int rt_cond_wait (RT_COND *cond, RT_MUTEX *mutex, RTIME timeout);

等待条件变量(具有相对标量超时)。

此例程是 rt_cond_wait_timed() 的一个变体,接受以标量值表示的相对超时规范。

参数

  • cond 条件变量描述符。
  • mutex 用于序列化对共享数据访问的互斥量的地址。
  • timeout 以时钟滴答表示的延迟。传递 TM_INFINITE 会导致调用者无限期阻塞。传递 TM_NONBLOCK 会导致调用者立即返回,而不会阻塞。

标签

xthread-only, switch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/mutex.h>
#include <alchemy/cond.h>

#define TASK_STACK_SIZE 0  // 使用默认栈大小
#define TASK_PRIORITY 50   // 中等优先级

RT_TASK producer_task, consumer_task;
RT_MUTEX mutex;
RT_COND cond;

int shared_data = 0;
int data_ready = 0;

void producer(void *arg)
{
    rt_task_sleep(1000000000);  // 睡眠1秒
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        shared_data++;
        printf("Producer: produced data %d\n", shared_data);
        data_ready = 1;
        
        rt_cond_signal(&cond);
        rt_mutex_release(&mutex);
        
        rt_task_sleep(1000000000);  // 睡眠1秒
    }
}

void consumer(void *arg)
{
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        while (!data_ready) {
            rt_cond_wait(&cond, &mutex, TM_INFINITE);
        }
        
        printf("Consumer: consumed data %d\n", shared_data);
        data_ready = 0;
        rt_mutex_release(&mutex);   
    }
}

int main(int argc, char *argv[])
{
    int ret;

    // 创建互斥锁
    ret = rt_mutex_create(&mutex, "example_mutex");
    if (ret) {
        fprintf(stderr, "Failed to create mutex: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    // 创建条件变量
    ret = rt_cond_create(&cond, "example_cond");
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建生产者任务
    ret = rt_task_create(&producer_task, "producer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create producer task: %s\n", strerror(-ret));
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建消费者任务
    ret = rt_task_create(&consumer_task, "consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&producer_task, &producer, NULL);
    rt_task_start(&consumer_task, &consumer, NULL);

    rt_task_join(&producer_task);
    rt_task_join(&consumer_task);
    rt_cond_delete(&cond);
    rt_mutex_delete(&mutex);

    return EXIT_SUCCESS;
}

rt_cond_wait_timed

int rt_cond_wait_timed (RT_COND *cond, RT_MUTEX *mutex, const struct timespec *abs_timeout);

等待条件变量。

此服务原子性地释放互斥量并阻塞调用任务,直到发出条件变量 cond 的信号或发生超时,以先到者为准。在从此服务返回之前,将重新获取互斥量。

参数

  • cond 条件变量描述符。
  • mutex 用于序列化对共享数据访问的互斥量的地址。
  • abs_timeout 一个以秒/纳秒表示的绝对日期,基于 Alchemy 时钟,指定等待条件变量被发出信号的时间限制。传递 NULL 会导致调用者无限期阻塞。传递 { .tv_sec = 0, .tv_nsec = 0 } 会导致调用者立即返回,而不会阻塞。

返回值

成功时返回零。否则:

  • 如果在发出条件变量的信号之前达到 abs_timeout,则返回 -ETIMEDOUT。
  • 如果 abs_timeout 是 { .tv_sec = 0, .tv_nsec = 0 },则返回 -EWOULDBLOCK。
  • 如果为当前任务调用了 rt_task_unblock(),则返回 -EINTR。
  • 如果 cond 不是有效的条件变量描述符,则返回 -EINVAL。
  • 如果在调用者等待条件变量时删除了 cond,则返回 -EIDRM。在此事件中,此服务返回时,cond 不再有效。
  • 如果此服务应阻塞,但未从 Xenomai 线程调用,则返回 -EPERM。

标签

xthread-only, switch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/mutex.h>
#include <alchemy/cond.h>

#define TASK_STACK_SIZE 0  // 使用默认栈大小
#define TASK_PRIORITY 50   // 中等优先级

RT_TASK producer_task, consumer_task;
RT_MUTEX mutex;
RT_COND cond;

int shared_data = 0;
int data_ready = 0;

void producer(void *arg)
{
    rt_task_sleep(1000000000);  // 睡眠1秒
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        shared_data++;
        printf("Producer: produced data %d\n", shared_data);
        data_ready = 1;
        
        rt_cond_signal(&cond);
        rt_mutex_release(&mutex);
        
        rt_task_sleep(3000000000);  // 睡眠3秒
    }
}

void consumer(void *arg)
{
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        while (!data_ready) {
            struct timespec ts;
            clock_gettime(CLOCK_MONOTONIC, &ts);
            ts.tv_sec += 2;
            int ret = rt_cond_wait_timed(&cond, &mutex, &ts);
            if (ret == -ETIMEDOUT) {
                printf("Consumer: Wait timed out.\n");
            }else if (ret == 0){
                printf("Consumer: Condition variable signaled\n");
            }else{
                printf("Consumer: Something went wrong\n");
            }
        }
        
        printf("Consumer: consumed data %d\n", shared_data);
        data_ready = 0;
        rt_mutex_release(&mutex);   
    }
}

int main(int argc, char *argv[])
{
    int ret;

    // 创建互斥锁
    ret = rt_mutex_create(&mutex, "example_mutex");
    if (ret) {
        fprintf(stderr, "Failed to create mutex: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    // 创建条件变量
    ret = rt_cond_create(&cond, "example_cond");
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建生产者任务
    ret = rt_task_create(&producer_task, "producer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create producer task: %s\n", strerror(-ret));
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建消费者任务
    ret = rt_task_create(&consumer_task, "consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&producer_task, &producer, NULL);
    rt_task_start(&consumer_task, &consumer, NULL);

    rt_task_join(&producer_task);
    rt_task_join(&consumer_task);
    rt_cond_delete(&cond);
    rt_mutex_delete(&mutex);

    return EXIT_SUCCESS;
}

rt_cond_wait_until

int rt_cond_wait_until (RT_COND *cond, RT_MUTEX *mutex, RTIME timeout);

等待条件变量(具有绝对标量超时)。

此例程是 rt_cond_wait_timed() 的一个变体,接受以标量值表示的绝对超时规范。

参数

  • cond 条件变量描述符。
  • mutex 用于序列化对共享数据访问的互斥量的地址。
  • abs_timeout 一个以时钟滴答表示的绝对日期。传递 TM_INFINITE 会导致调用者无限期阻塞。传递 TM_NONBLOCK 会导致调用者立即返回,而不会阻塞。

标签

xthread-only, switch-primary

示例代码

c{filename="app.c"} 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/mutex.h>
#include <alchemy/cond.h>

#define TASK_STACK_SIZE 0  // 使用默认栈大小
#define TASK_PRIORITY 50   // 中等优先级

RT_TASK producer_task, consumer_task;
RT_MUTEX mutex;
RT_COND cond;

int shared_data = 0;
int data_ready = 0;

void producer(void *arg)
{
    rt_task_sleep(1000000000);  // 睡眠1秒
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        shared_data++;
        printf("Producer: produced data %d\n", shared_data);
        data_ready = 1;
        
        rt_cond_signal(&cond);
        rt_mutex_release(&mutex);
        
        rt_task_sleep(3000000000);  // 睡眠3秒
    }
}

void consumer(void *arg)
{
    while (shared_data < 5) {
        rt_mutex_acquire(&mutex, TM_INFINITE);
        
        while (!data_ready) {
            RTIME timeout = rt_timer_read() + 2000000000;
            int ret = rt_cond_wait_until(&cond, &mutex, timeout);
            if (ret == -ETIMEDOUT) {
                printf("Consumer: Wait timed out.\n");
            }else if (ret == 0){
                printf("Consumer: Condition variable signaled\n");
            }else{
                printf("Consumer: Something went wrong\n");
            }
        }
        
        printf("Consumer: consumed data %d\n", shared_data);
        data_ready = 0;
        rt_mutex_release(&mutex);   
    }
}

int main(int argc, char *argv[])
{
    int ret;

    // 创建互斥锁
    ret = rt_mutex_create(&mutex, "example_mutex");
    if (ret) {
        fprintf(stderr, "Failed to create mutex: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    // 创建条件变量
    ret = rt_cond_create(&cond, "example_cond");
    if (ret) {
        fprintf(stderr, "Failed to create condition variable: %s\n", strerror(-ret));
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建生产者任务
    ret = rt_task_create(&producer_task, "producer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create producer task: %s\n", strerror(-ret));
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 创建消费者任务
    ret = rt_task_create(&consumer_task, "consumer", TASK_STACK_SIZE, TASK_PRIORITY, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create consumer task: %s\n", strerror(-ret));
        rt_task_delete(&producer_task);
        rt_cond_delete(&cond);
        rt_mutex_delete(&mutex);
        return EXIT_FAILURE;
    }

    // 启动任务
    rt_task_start(&producer_task, &producer, NULL);
    rt_task_start(&consumer_task, &consumer, NULL);

    rt_task_join(&producer_task);
    rt_task_join(&consumer_task);
    rt_cond_delete(&cond);
    rt_mutex_delete(&mutex);

    return EXIT_SUCCESS;
}

最近修改: 2025-07-24