lock 的范围 ,仍会改变 i 的值

探讨了在C#中使用定时器与锁机制时,不同的锁位置如何影响线程安全性和变量i的值更新。通过两个代码示例对比,说明了在执行布尔值切换和文本打印操作时,锁的位置对于防止竞态条件的重要性。
 private static void Timer_ChangeBoolValue(object sender, ElapsedEventArgs e)
        {
            lock (_lock)
            {
                if (i % 2 == 0)
                {
                    Test.isCallBox = false;
                }
                else
                {
                    Test.isCallBox = true;
                }
                i++;

                Test.PrintText();
            }
        }

与 
 private static void Timer_ChangeBoolValue(object sender, ElapsedEventArgs e)
        {

            if (i % 2 == 0)
            {
                Test.isCallBox = false;
            }
            else
            {
                Test.isCallBox = true;
            }
            i++;
            lock (_lock)
            {
                Test.PrintText();
            }
        }

锁的效果是不一样的, 下面的仍会改变 i 的值

 

xdata uint16 temp_ad_val[sample_num]; xdata float ad_average[3] = {0.0f,0.0f,0.0f}; xdata float ad_rms[3] = {0.0f,0.0f,0.0f}; xdata float temp_voltage[3] = {0.0f,0.0f,0.0f}; xdata float Freq = 0.0f; xdata float Voltage[3] = {0.0f,0.0f,0.0f}; xdata float Current[3] = {0.0f,0.0f,0.0f}; xdata uint16 PWM1_Duty = 666; xdata uint16 calibration_in_progress[3] = {0}; //xdata uint16 test_ad[sample_num]; #define RMS_WINDOW_SIZE 8 // 第一级:RMS的窗口大小(建议5~10) #define VOLTAGE_WINDOW_SIZE 10 // 第二级:最终电压窗口大小 // RMS 中间窗口(每通道) xdata float rms_window[3][RMS_WINDOW_SIZE]; xdata uint8 rms_window_index[3]; xdata uint8 rms_window_filled[3]; // 最终电压窗口(已有) xdata float voltage_window[3][VOLTAGE_WINDOW_SIZE]; // 原名不变 xdata uint8 window_index[3]; xdata uint8 window_filled[3]; // 标志:是否已填满一圈 void init_filters(void) { uint8 ch, i; // 初始化 RMS 滤波器 for (ch = 0; ch < 3; ch++) { for (i = 0; i < RMS_WINDOW_SIZE; i++) { rms_window[ch][i] = 0.0f; } rms_window_index[ch] = 0; rms_window_filled[ch] = 0; } // 初始化电压滤波器 for (ch = 0; ch < 3; ch++) { for (i = 0; i < VOLTAGE_WINDOW_SIZE; i++) { voltage_window[ch][i] = 0.0f; } window_index[ch] = 0; window_filled[ch] = 0; } } float moving_average_rms(uint8 ch, float new_rms) { uint8 i; float sum = 0.0f; // 写入新 rms_window[ch][rms_window_index[ch]] = new_rms; rms_window_index[ch] = (rms_window_index[ch] + 1) % RMS_WINDOW_SIZE; // 更新填充计数 if (rms_window_filled[ch] < RMS_WINDOW_SIZE) { rms_window_filled[ch]++; } // 求和 for (i = 0; i < rms_window_filled[ch]; i++) { sum += rms_window[ch][i]; } return sum / rms_window_filled[ch]; // 动态除法,避免启动跳变 } float moving_average_voltage(uint8 ch, float new_voltage) { uint8 i; float sum = 0.0f; voltage_window[ch][window_index[ch]] = new_voltage; window_index[ch] = (window_index[ch] + 1) % VOLTAGE_WINDOW_SIZE; if (window_filled[ch] < VOLTAGE_WINDOW_SIZE) { window_filled[ch]++; } for (i = 0; i < window_filled[ch]; i++) { sum += voltage_window[ch][i]; } return sum / window_filled[ch]; } /*************************************************************************************************** * 函数名称: Compute_Voltage * 函数功能: 通讯处理函数 * 入口参数: 无 * 出口参数: 无 * 使用说明:滤波 * 创建日期: * 修改日期:2025年08月18日 * 修改原因: ***************************************************************************************************/ void Compute_Voltage(void) { uint8 i,j; float temp_rms[3] = {0.0,0.0,0.0}; // float diff, delta; for(j=0; j<3; j++) { uart_com_unpack(); for(i=0; i<sample_num; i++) { temp_ad_val[i] = adc_val[j][i]; } ad_average[j] = Average_Precess(&temp_ad_val,sample_num); temp_rms[j] = RMS_Process(&temp_ad_val,sample_num,ad_average[j]); //memset(temp_ad_val,0,100*sizeof(uint16)); // ★★★ 第一级滤波:RMS 滑动窗口平均 ★★★ ad_rms[j] = moving_average_rms(j, temp_rms[j] ); } //*******************************************// //***********这里预留一个量程****************// //*******************************************// for(i=0; i<3; i++) //用for循环可以节省flash 后面可以合并 { uart_com_unpack(); temp_voltage[i] = (float)(ad_rms[i]*1000.0f/base_info.V_K[i]); // 在电压计算循环中加入: if(calibration_lock[i]) { // 校准锁定模式下,范围内保持锁定 if(fabs(Voltage[i] - modbus_rx_data) < 5.0f) { Voltage[i] = modbus_rx_data; } else { calibration_lock[i] = 0; // 超出范围解除锁定 } } else{ if(temp_voltage[i] <=30.0f) //小于2V清零 Voltage[i] = 0.0f; else { // ★★★ 第二级滤波:电压滑动窗口平均 ★★★ Voltage[i] = moving_average_voltage(i, temp_voltage[i]); } } } }***************************************************************************************************/ void main(void) { uint8 i = 0; sys_init(); init_filters(); while(1) { WT_init(); Compute_Voltage(); if(0 == compute_flag) { Compute_Current(); if(1 == freq_start_flag) //当串口调整PWM时,不进行采样频率切换 { Freq = (float)((10000.0f/int0_time_50)+0.5f)*100.0f; // 1000/(time*5/100) *100 //Freq = (1000.0f/(int0_time_50*5.0f/INT_NUM)) *100.0f; change_sample_freq(); freq_start_flag =0; //计算完毕,等待下一次计算采样频率 T_cpmpute_flag = 0; //外部中断重新开始计数 int0_time_50 = 0; //计时时间清零 } } // 超时处理 if(uart_rx_time_start && !uart_rx_finish_ifg) { if(com_err_time++ > 500) { uart_rx_time_start = 0; // 重置计数 uart_rx_count = 0; for(i = 0; i < sizeof(uart_rx_buf); i++) { uart_rx_buf[i] = 0; } } } uart_com_unpack(); } } 如上修改后第一二路通道电压503v504v只有第三路校准为500v,但三路电压‘’还是一点点向上增长
最新发布
12-11
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值