多任务全局共享变量问题

说明:

  • 函数中全局变量加global,改变内存地址的时候需加global,如果修改了全局变量的内存地址改变了,必须使用global,如果仅仅修改了原来内存空间中的数据,此时不用必须使用global
  • 数字,字符串,元组不可变,必须加global

共享全局变量

import threading
import time


g_num = 100


def test1(temp):
    global g_num
    g_num += 1
    temp.append(33)
    print("--------in test1 g_num = %d" % g_num) 
    print("--------in test1 g_nums = %s" % str(temp)) 


def test2(temp):
    print("--------in test2 g_num = %d"% g_num)
    print("--------in test2 g_nums = %s"% str(temp))


g_nums = [11,22]

def main():
    # target指定将来,这个线程去哪个函数执行
    # args指定函数执行时传递的参数
    t1 = threading.Thread(target = test1, args=(g_nums,))
    t2 = threading.Thread(target = test2, args=(g_nums,))

    t1.start()
    time.sleep(1)
    
    t2.start()
    time.sleep(1)

    print
### RTOS中多任务环境下全局变量的安全读写 在实时操作系统(RTOS)环境中,多个任务可能会并发访问同一个全局变量。这种情况下,如果不对这些操作加以控制,则可能导致竞态条件(Race Condition)。为了确保数据的一致性和安全性,在RTOS中通常采用以下几种方法来处理全局变量的同步问题。 #### 使用 `volatile` 关键字 当某个全局变量可能被中断服务程序或其他任务修改时,应该将其声明为 `volatile` 类型[^4]。这样可以防止编译器对该变量进行优化而导致不可预期的行为。然而需要注意的是,虽然 `volatile` 可以阻止编译器缓存该变量值,但它并不能解决多任务间的竞争问题。 #### 中断禁用与使能 一种简单粗暴的方式是在访问临界区之前暂时屏蔽掉更高优先级的任务或者中断源。具体做法是进入临界区前调用函数关闭中断;退出临界区后再重新开启中断。这种方法能够有效避免其他高优先级任务打断当前正在运行的操作序列,从而保护共享资源不受到破坏。不过频繁开关中断会影响系统的响应速度以及增加功耗等问题,因此需谨慎使用此策略[^1]。 ```c void critical_section_access(volatile int *shared_var){ unsigned char old_status; // Save current interrupt status and disable interrupts. old_status = portSET_INTERRUPT_MASK_FROM_ISR(); (*shared_var)++; // Restore previous interrupt state after leaving the critical section. portCLEAR_INTERRUPT_MASK_FROM_ISR(old_status); } ``` #### 利用互斥锁(Mutex) 对于较长时间占用公共资源的情形来说,利用Mutex更为合适一些。每个需要独占某项特定资源的任务都必须先获取相应的mutex才能继续执行下去;而释放这个mutex之后其它等待中的任务才有可能获得许可并开始工作。这种方式相比单纯依靠关中断而言更加精细可控,并且不会影响整个CPU级别的中断行为[^2]。 ```c SemaphoreHandle_t xMutex; // Initialize mutex at startup code somewhere... xMutex = xSemaphoreCreateMutex(); if( pdTRUE == xSemaphoreTake(xMutex, (TickType_t)10 ) ){ /* Critical Section */ shared_resource++; xSemaphoreGive(xMutex); }else{ /* Failed to obtain Mutex within timeout period */ } ``` #### 应用任务通知(Task Notifications) 随着版本迭代更新,FreeRTOS引入了一种叫做“任务通知”的新特性作为轻量化替代传统IPC手段的选择之一。它允许直接向目标任务发送消息而不必借助额外的数据结构比如队列之类的中间件组件。而且由于其内部实现原理的缘故,在性能表现上也优于传统的信号量机制大约有百分之四十五左右的优势同时还能节省约三分之一数量级以上的RAM存储开销[^3]。 ```c BaseType_t xHigherPriorityTaskWoken = pdFALSE; /* Notify another task that an event has occurred. */ vTaskNotifyGiveFromISR( xTaskToNotify,&xHigherPriorityTaskWoken ); portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); ``` 综上所述,在RTOS系统里针对不同应用场景可以选择合适的办法去保障多任务之间共同使用的那些重要参数免受意外更改的影响。无论是简单的volatile标记还是复杂的semaphore/mutex管理亦或是高效的task notification运用都需要依据实际需求合理选用最佳方案。 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值