计数信号量 IPC 机制。
计数信号量是一种同步对象,用于控制多个实时任务访问资源时允许的并发级别,基于原子访问的计数变量的值。信号量通过 P(“Proberen”,荷兰语中的“测试和递减”)和 V(“Verhogen”,递增)操作来使用。P 操作在计数非零时将信号量计数减一,或者等待直到另一个任务发出 V 操作。相反,V 操作通过将计数加一来释放资源,如果有任务在等待 P 操作,则解除其阻塞。等待信号量可能导致优先级反转。
如果在任何时候最多只有一个资源可用,信号量将强制互斥,因此可以用于串行化对临界区的访问。然而,应使用互斥锁来防止基于优先级继承协议的优先级反转。
int rt_sem_bind (RT_SEM *sem, const char *name, RTIME timeout);
绑定到信号量。
此例程创建一个新的描述符,以引用由其符号名称标识的现有信号量。如果在进入时对象不存在,调用者可能会阻塞,直到创建具有给定名称的信号量。
参数
返回值
成功时返回零。否则:
标签
xthread-nowait
, switch-primary
注释
超时值被解释为 Alchemy 时钟分辨率的倍数(见 --alchemy-clock-resolution 选项,默认为 1 纳秒)。
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define TASK_PRIO 50
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0
RT_TASK producer_task, consumer_task;
RT_SEM sem;
int data = 0;
void producer(void *arg)
{
RT_SEM sem_producer;
int ret = rt_sem_bind(&sem_producer, "MySemaphore", TM_INFINITE);
if (ret < 0) {
printf("Error bind semaphore: %d\n", ret);
return;
}
while (data < 3) {
printf("Producer: Producing item\n");
rt_task_sleep(1000000000); // 睡眠 1 秒
data++;
rt_sem_v(&sem_producer);
printf("Producer: Item produced\n");
}
ret = rt_sem_unbind(&sem_producer);
if (ret < 0) {
printf("Error unbind semaphore: %d\n", ret);
return;
}
}
void consumer(void *arg)
{
RT_SEM sem_consumer;
int ret = rt_sem_bind(&sem_consumer, "MySemaphore", TM_INFINITE);
if (ret < 0) {
printf("Error bind semaphore: %d\n", ret);
return;
}
while (data < 3) {
printf("Consumer: Waiting for item\n");
rt_sem_p(&sem_consumer, TM_INFINITE);
printf("Consumer: Item consumed, data = %d\n\n",data);
}
ret = rt_sem_unbind(&sem_consumer);
if (ret < 0) {
printf("Error unbind semaphore: %d\n", ret);
return;
}
}
int main(int argc, char *argv[])
{
int ret;
// 创建信号量
ret = rt_sem_create(&sem, "MySemaphore", 0, S_FIFO);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return EXIT_FAILURE;
}
// 创建生产者任务
ret = rt_task_create(&producer_task, "Producer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating producer task: %d\n", ret);
goto cleanup_sem;
}
// 创建消费者任务
ret = rt_task_create(&consumer_task, "Consumer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_producer;
}
// 启动任务
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_task_delete(&consumer_task);
cleanup_producer:
rt_task_delete(&producer_task);
cleanup_sem:
rt_sem_delete(&sem);
return EXIT_SUCCESS;
}
int rt_sem_broadcast (RT_SEM *sem);
广播信号量。
所有当前等待信号量的任务将立即解除阻塞。信号量计数被设置为零。
参数
返回值
成功时返回零。否则:
标签
unrestricted
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define TASK_PRIO 50
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0
RT_TASK producer_task, consumer_task1, consumer_task2;
RT_SEM sem;
int data = 0;
void producer(void *arg)
{
while (data < 3) {
printf("Producer: Producing item\n");
rt_task_sleep(1000000000); // 睡眠 1 秒
data++;
rt_sem_broadcast(&sem);
printf("Producer: Item produced\n\n");
}
}
void consumer(void *arg)
{
int task_id = (int)(long)arg;
while (data < 3) {
printf("Consumer %d: Waiting for item\n",task_id);
rt_sem_p(&sem, TM_INFINITE);
printf("Consumer %d: Item consumed, data = %d\n",task_id,data);
}
}
int main(int argc, char *argv[])
{
int ret;
// 创建信号量
ret = rt_sem_create(&sem, "MySemaphore", 0, S_FIFO);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return EXIT_FAILURE;
}
// 创建生产者任务
ret = rt_task_create(&producer_task, "Producer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating producer task: %d\n", ret);
goto cleanup_sem;
}
// 创建消费者任务1
ret = rt_task_create(&consumer_task1, "Consumer1", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_producer;
}
// 创建消费者任务2
ret = rt_task_create(&consumer_task2, "Consumer2", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_consumer;
}
// 启动任务
rt_task_start(&producer_task, &producer, NULL);
rt_task_start(&consumer_task1, &consumer, (void *)1);
rt_task_start(&consumer_task2, &consumer, (void *)2);
// 等待任务完成
rt_task_join(&producer_task);
rt_task_join(&consumer_task1);
rt_task_join(&consumer_task2);
// 清理
rt_task_delete(&consumer_task2);
cleanup_consumer:
rt_task_delete(&consumer_task1);
cleanup_producer:
rt_task_delete(&producer_task);
cleanup_sem:
rt_sem_delete(&sem);
return EXIT_SUCCESS;
}
int rt_sem_create (RT_SEM *sem, const char *name, unsigned long icount, int mode);
创建计数信号量。
参数
返回值
成功时返回零。否则:
标签
xthread-only
, mode-unrestricted
, switch-secondary
注意
信号量可以由属于同一 Xenomai 会话的多个进程共享。
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define TASK_PRIO 50
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0
RT_TASK producer_task, consumer_task;
RT_SEM sem;
int data = 0;
void producer(void *arg)
{
while (data < 3) {
printf("Producer: Producing item\n");
rt_task_sleep(1000000000); // 睡眠 1 秒
data++;
rt_sem_v(&sem);
printf("Producer: Item produced\n");
}
}
void consumer(void *arg)
{
while (data < 3) {
printf("Consumer: Waiting for item\n");
rt_sem_p(&sem, TM_INFINITE);
printf("Consumer: Item consumed, data = %d\n\n",data);
}
}
int main(int argc, char *argv[])
{
int ret;
// 创建信号量
ret = rt_sem_create(&sem, "MySemaphore", 0, S_FIFO);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return EXIT_FAILURE;
}
// 创建生产者任务
ret = rt_task_create(&producer_task, "Producer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating producer task: %d\n", ret);
goto cleanup_sem;
}
// 创建消费者任务
ret = rt_task_create(&consumer_task, "Consumer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_producer;
}
// 启动任务
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_task_delete(&consumer_task);
cleanup_producer:
rt_task_delete(&producer_task);
cleanup_sem:
rt_sem_delete(&sem);
return EXIT_SUCCESS;
}
int rt_sem_delete (RT_SEM *sem);
删除信号量。
此例程删除之前通过调用 rt_sem_create() 创建的信号量。
参数
返回值
成功时返回零。否则:
标签
mode-unrestricted
, switch-secondary
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define TASK_PRIO 50
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0
RT_TASK producer_task, consumer_task;
RT_SEM sem;
int data = 0;
void producer(void *arg)
{
while (data < 3) {
printf("Producer: Producing item\n");
rt_task_sleep(1000000000); // 睡眠 1 秒
data++;
rt_sem_v(&sem);
printf("Producer: Item produced\n");
}
}
void consumer(void *arg)
{
while (data < 3) {
printf("Consumer: Waiting for item\n");
rt_sem_p(&sem, TM_INFINITE);
printf("Consumer: Item consumed, data = %d\n\n",data);
}
}
int main(int argc, char *argv[])
{
int ret;
// 创建信号量
ret = rt_sem_create(&sem, "MySemaphore", 0, S_FIFO);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return EXIT_FAILURE;
}
// 创建生产者任务
ret = rt_task_create(&producer_task, "Producer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating producer task: %d\n", ret);
goto cleanup_sem;
}
// 创建消费者任务
ret = rt_task_create(&consumer_task, "Consumer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_producer;
}
// 启动任务
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_task_delete(&consumer_task);
cleanup_producer:
rt_task_delete(&producer_task);
cleanup_sem:
rt_sem_delete(&sem);
return EXIT_SUCCESS;
}
int rt_sem_inquire (RT_SEM *sem, RT_SEM_INFO *info);
查询信号量状态。
此例程返回指定信号量的状态信息。
参数
返回值
成功时返回零,并将状态信息写入 info 指向的结构体。否则:
标签
unrestricted
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define TASK_PRIO 50
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0
RT_TASK producer_task, consumer_task;
RT_SEM sem;
int data = 0;
void producer(void *arg)
{
int ret = 0;
RT_SEM_INFO info;
while (data < 3) {
printf("Producer: Producing item\n");
rt_task_sleep(1000000000); // 睡眠 1 秒
data++;
rt_sem_v(&sem);
ret = rt_sem_inquire(&sem, &info);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return;
}
printf("Producer: Get info:\n");
printf(" name:%s, nwaiters:%d, sem_value:%ld\n",info.name,info.nwaiters,info.count);
printf("Producer: Item produced\n");
}
}
void consumer(void *arg)
{
while (data < 3) {
printf("Consumer: Waiting for item\n");
rt_sem_p(&sem, TM_INFINITE);
printf("Consumer: Item consumed, data = %d\n\n",data);
}
}
int main(int argc, char *argv[])
{
int ret;
// 创建信号量
ret = rt_sem_create(&sem, "MySemaphore", 0, S_FIFO);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return EXIT_FAILURE;
}
// 创建生产者任务
ret = rt_task_create(&producer_task, "Producer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating producer task: %d\n", ret);
goto cleanup_sem;
}
// 创建消费者任务
ret = rt_task_create(&consumer_task, "Consumer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_producer;
}
// 启动任务
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_task_delete(&consumer_task);
cleanup_producer:
rt_task_delete(&producer_task);
cleanup_sem:
rt_sem_delete(&sem);
return EXIT_SUCCESS;
}
int rt_sem_p (RT_SEM *sem, RTIME timeout);
等待信号量(带相对标量超时)。
此例程是 rt_sem_p_timed() 的变体,接受以标量值表示的相对超时规范。
参数
标签
xthread-nowait
, switch-primary
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define TASK_PRIO 50
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0
RT_TASK producer_task, consumer_task;
RT_SEM sem;
int data = 0;
void producer(void *arg)
{
while (data < 3) {
printf("Producer: Producing item\n");
rt_task_sleep(1000000000); // 睡眠 1 秒
data++;
rt_sem_v(&sem);
printf("Producer: Item produced\n");
}
}
void consumer(void *arg)
{
while (data < 3) {
printf("Consumer: Waiting for item\n");
ret = rt_sem_p(&sem, TM_INFINITE);
printf("Consumer: Item consumed, data = %d\n\n",data);
}
}
int main(int argc, char *argv[])
{
int ret;
// 创建信号量
ret = rt_sem_create(&sem, "MySemaphore", 0, S_FIFO);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return EXIT_FAILURE;
}
// 创建生产者任务
ret = rt_task_create(&producer_task, "Producer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating producer task: %d\n", ret);
goto cleanup_sem;
}
// 创建消费者任务
ret = rt_task_create(&consumer_task, "Consumer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_producer;
}
// 启动任务
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_task_delete(&consumer_task);
cleanup_producer:
rt_task_delete(&producer_task);
cleanup_sem:
rt_sem_delete(&sem);
return EXIT_SUCCESS;
}
int rt_sem_p_timed (RT_SEM *sem, const struct timespec *abs_timeout);
等待信号量(带绝对时间超时)。
测试并递减信号量计数。如果信号量值大于零,则将其递减一,并立即返回给调用者。否则,调用者将被阻塞,直到信号量被发出或销毁,除非要求非阻塞操作。
参数
返回值
成功时返回零。否则:
标签
xthread-nowait
, switch-primary
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define TASK_PRIO 50
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0
RT_TASK producer_task, consumer_task;
RT_SEM sem;
int data = 0;
void producer(void *arg)
{
while (data < 3) {
printf("Producer: Producing item\n");
if(data == 0) {
rt_task_sleep(2000000000); // 睡眠 2 秒, 触发超时
}
rt_task_sleep(1000000000); // 睡眠 1 秒
data++;
rt_sem_v(&sem);
printf("Producer: Item produced\n");
}
}
void consumer(void *arg)
{
struct timespec ts;
int ret;
while (data < 3) {
printf("Consumer: Waiting for item\n");
clock_gettime(CLOCK_MONOTONIC, &ts);
ts.tv_sec += 2; // 超时时间 2 秒
ret = rt_sem_p_timed(&sem, &ts);
if(ret == 0){
printf("Consumer: Item consumed, data = %d\n\n",data);
}else if(ret == -ETIMEDOUT)
{
printf("Consumer: Timeout while waiting for semaphore.\n");
}else{
printf("Consumer: Error while waiting for semaphore: %d\n", ret);
}
}
}
int main(int argc, char *argv[])
{
int ret;
// 创建信号量
ret = rt_sem_create(&sem, "MySemaphore", 0, S_FIFO);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return EXIT_FAILURE;
}
// 创建生产者任务
ret = rt_task_create(&producer_task, "Producer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating producer task: %d\n", ret);
goto cleanup_sem;
}
// 创建消费者任务
ret = rt_task_create(&consumer_task, "Consumer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_producer;
}
// 启动任务
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_task_delete(&consumer_task);
cleanup_producer:
rt_task_delete(&producer_task);
cleanup_sem:
rt_sem_delete(&sem);
return EXIT_SUCCESS;
}
int rt_sem_p_until (RT_SEM *sem, RTIME abs_timeout);
等待信号量(带绝对标量超时)。
此例程是 rt_sem_p_timed() 的变体,接受以标量值表示的绝对超时规范。
参数
标签
xthread-nowait
, switch-primary
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define TASK_PRIO 50
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0
RT_TASK producer_task, consumer_task;
RT_SEM sem;
int data = 0;
void producer(void *arg)
{
while (data < 3) {
printf("Producer: Producing item\n");
if(data == 0) {
rt_task_sleep(2000000000); // 睡眠 2 秒, 触发超时
}
rt_task_sleep(1000000000); // 睡眠 1 秒
data++;
rt_sem_v(&sem);
printf("Producer: Item produced\n");
}
}
void consumer(void *arg)
{
RTIME timeout;
int ret;
while (data < 3) {
printf("Consumer: Waiting for item\n");
timeout = rt_timer_read() + 2000000000; // 超时时间 2 秒
ret = rt_sem_p_until(&sem, timeout);
if(ret == 0){
printf("Consumer: Item consumed, data = %d\n\n",data);
}else if(ret == -ETIMEDOUT)
{
printf("Consumer: Timeout while waiting for semaphore.\n");
}else{
printf("Consumer: Error while waiting for semaphore: %d\n", ret);
}
}
}
int main(int argc, char *argv[])
{
int ret;
// 创建信号量
ret = rt_sem_create(&sem, "MySemaphore", 0, S_FIFO);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return EXIT_FAILURE;
}
// 创建生产者任务
ret = rt_task_create(&producer_task, "Producer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating producer task: %d\n", ret);
goto cleanup_sem;
}
// 创建消费者任务
ret = rt_task_create(&consumer_task, "Consumer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_producer;
}
// 启动任务
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_task_delete(&consumer_task);
cleanup_producer:
rt_task_delete(&producer_task);
cleanup_sem:
rt_sem_delete(&sem);
return EXIT_SUCCESS;
}
int rt_sem_unbind (RT_SEM *sem);
解除信号量绑定。
参数
此例程释放之前对信号量的绑定。此调用返回后,描述符将不再有效,无法再引用该对象。
标签
thread-unrestricted
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define TASK_PRIO 50
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0
RT_TASK producer_task, consumer_task;
RT_SEM sem;
int data = 0;
void producer(void *arg)
{
RT_SEM sem_producer;
int ret = rt_sem_bind(&sem_producer, "MySemaphore", TM_INFINITE);
if (ret < 0) {
printf("Error bind semaphore: %d\n", ret);
return;
}
while (data < 3) {
printf("Producer: Producing item\n");
rt_task_sleep(1000000000); // 睡眠 1 秒
data++;
rt_sem_v(&sem_producer);
printf("Producer: Item produced\n");
}
ret = rt_sem_unbind(&sem_producer);
if (ret < 0) {
printf("Error unbind semaphore: %d\n", ret);
return;
}
}
void consumer(void *arg)
{
RT_SEM sem_consumer;
int ret = rt_sem_bind(&sem_consumer, "MySemaphore", TM_INFINITE);
if (ret < 0) {
printf("Error bind semaphore: %d\n", ret);
return;
}
while (data < 3) {
printf("Consumer: Waiting for item\n");
rt_sem_p(&sem_consumer, TM_INFINITE);
printf("Consumer: Item consumed, data = %d\n\n",data);
}
ret = rt_sem_unbind(&sem_consumer);
if (ret < 0) {
printf("Error unbind semaphore: %d\n", ret);
return;
}
}
int main(int argc, char *argv[])
{
int ret;
// 创建信号量
ret = rt_sem_create(&sem, "MySemaphore", 0, S_FIFO);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return EXIT_FAILURE;
}
// 创建生产者任务
ret = rt_task_create(&producer_task, "Producer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating producer task: %d\n", ret);
goto cleanup_sem;
}
// 创建消费者任务
ret = rt_task_create(&consumer_task, "Consumer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_producer;
}
// 启动任务
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_task_delete(&consumer_task);
cleanup_producer:
rt_task_delete(&producer_task);
cleanup_sem:
rt_sem_delete(&sem);
return EXIT_SUCCESS;
}
int rt_sem_v (RT_SEM *sem);
发出信号量。
如果信号量处于挂起状态,等待队列中的任务将立即解除阻塞。否则,信号量计数将增加一,除非信号量以“脉冲”模式使用(参见 rt_sem_create())。
参数
返回值
成功时返回零。否则:
标签
unrestricted
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define TASK_PRIO 50
#define TASK_MODE T_JOINABLE
#define TASK_STKSZ 0
RT_TASK producer_task, consumer_task;
RT_SEM sem;
int data = 0;
void producer(void *arg)
{
while (data < 3) {
printf("Producer: Producing item\n");
rt_task_sleep(1000000000); // 睡眠 1 秒
data++;
rt_sem_v(&sem);
printf("Producer: Item produced\n");
}
}
void consumer(void *arg)
{
while (data < 3) {
printf("Consumer: Waiting for item\n");
rt_sem_p(&sem, TM_INFINITE);
printf("Consumer: Item consumed, data = %d\n\n",data);
}
}
int main(int argc, char *argv[])
{
int ret;
// 创建信号量
ret = rt_sem_create(&sem, "MySemaphore", 0, S_FIFO);
if (ret < 0) {
printf("Error creating semaphore: %d\n", ret);
return EXIT_FAILURE;
}
// 创建生产者任务
ret = rt_task_create(&producer_task, "Producer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating producer task: %d\n", ret);
goto cleanup_sem;
}
// 创建消费者任务
ret = rt_task_create(&consumer_task, "Consumer", TASK_STKSZ, TASK_PRIO, TASK_MODE);
if (ret < 0) {
printf("Error creating consumer task: %d\n", ret);
goto cleanup_producer;
}
// 启动任务
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_task_delete(&consumer_task);
cleanup_producer:
rt_task_delete(&producer_task);
cleanup_sem:
rt_sem_delete(&sem);
return EXIT_SUCCESS;
}