0

因为 Contiki 提供的内置列表不符合我的需求(使用太多内存),所以我已经实现了我自己的列表版本,该版本已经针对我打算如何使用它进行了优化。

在任何时候,都会有一个列表被多个进程/原型线程操作(即添加/删除元素)。但是,添加/删除不会发生在进程/protothread 块中,而是在通过进程/protothread 发起的一系列函数调用调用的函数中调用。

例如,

void funct2()
{
    // add or remove element from shared list
}

void func1()
{
    // some stuff
    func2();
    // more stuff
}

PROCESS_THREAD(temp1, ev, data)
{
    PROCESS_BEGIN();
    func1();
    PROCESS_END();
}

PROCESS_THREAD(temp2, ev, data)
{
    PROCESS_BEGIN();
    func1();
    PROCESS_END();
}

结果,我不能使用 Contiki 的内置机制来创建互斥锁(通过 using pt-sem.h),因为它必须出现在进程/原型线程块中。这是因为虽然我可以在实际的进程块中创建一个锁(见下文),但这将导致阻塞进程比必要的时间长得多

PROCESS_THREAD(temp2, ev, data)
{
    PROCESS_BEGIN();
    // get lock
    func1();
    // release lock
    PROCESS_END();
}

这是非常有问题的,因为从我的列表中添加和删除元素不是原子的;如果在向列表中删除或添加元素时发生中断,事情将无法正常运行。是否可以轻松地做我想做的事;即从函数调用中的列表中原子地添加和删除元素,而不是在进程/原型线程块中?

4

1 回答 1

0

您似乎对 protothreads 的作用感到困惑。protothread 方法是协作调度的一种形式。当执行流程要求让步时,原型线程只能在特定点让步。中断永远不能将执行流程切换到另一个原型线程。

因此,有两种不同的选择:

1) 如果您的列表同时从 protothread 和中断处理程序上下文访问,您需要在禁用中断的情况下对列表进行所有修改。因此,您的锁定/解锁代码分别是禁用/启用中断。

2)如果您的列表只能从 protothreads 访问,则不需要任何锁定。这是推荐的设计。

事实上,使用 protothreads 的主要优点是在 99% 的情况下不需要锁。

于 2018-05-29T12:18:55.897 回答