前情回顾#static_thread

本文解释了类的静态成员与非静态成员的区别,并详细探讨了线程安全问题的成因及解决方案,包括同步锁的使用及如何通过ThreadLocal确保线程安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

static理解:

程序最终都将在内存中执行,变量只有在内存中占有一席之地时才能被访问。

类的静态成员(变量和方法)属于类本身,在类加载的时候就会分配内存,可以通过类名直接去访问;

非静态成员(变量和方法)属于类的对象,所以只有在类的对象产生(创建类的实例)时才会分配内存,然后通过类的对象(实例)去访问。

在一个类的静态成员中去访问其非静态成员之所以会出错,

是因为在类的非静态成员不存在的时候类的静态成员就已经存在了,访问一个内存中不存在的东西当然会出错


线程:

进程的概念:进程是一个静态的概念,

程序的执行过程:

先把程序加载进代码区准备,

这时程序还没有开始执行,这叫一个进程

进程执行实际上是指进程的主线程执行了.


一个cpu同个时间点只能有一个线程被执行,

想要实现真正的多线程只能依靠多个cpu或多核


开启一个新线程的方法:运行start方法,别无他法


存在线程安全问题的原因:

多个线程同时操作一个资源

比如A和B同时取钱,一共三千,一人取两千,账户余额还有一千

也就是说一个线程执行的过程中被另一个资源夺走了执行权

比如A查询账户和取钱的动作没有一气呵成,中间被B查询取钱的动作中断了,这就是原因


解决线程不安全的方法:

synchronize锁住当前线程对象:意思是一个线程执行到被锁住的区域中时,不会被其他线程打断.


多线程死锁问题:



1.线程安全

多线程多次执行同样的代码,总能获得确定的结果,即不存在不确定的竞争,那么就称这段代码为Thread-safe.

2.如何线程安全地使用非安全对象

有些类是别人写的,自己不能再修改源码,那么如何做到安全地并发使用呢?

1️⃣局部变量

2️⃣加锁

3️⃣为每个线程维护一个对象


将对象绑定到当前线程:

Java.lang.ThreadLocal<T>

类,对它的调用在不同线程中有不同的结果。

1.使用场景

有些类不是线程安全的,若想在多线程下使用,我们可以为每个线程绑定一个此类的对象。

2.常用方法

T java.lang.ThreadLocal.get()
返回当前线程所持有的对象。
void java.lang.ThreadLocal.set(T value)
设置当前线程所持有的对象。
void java.lang.ThreadLocal.remove()
移除当前线程所持有的对象。


# 创建一个全局的循环队列以及全局共享变量 from queue import Queue global_data=[] global_queue = Queue() from datetime import datetime from threading import Thread import serial, re, math from flask import Flask, render_template, request, jsonify from pyecharts import options as opts from pyecharts.charts import Line import matplotlib.pyplot as plt import numpy from kalman5 import * from wifilib import * import mysql.connector from random import randrange from flask import Flask, render_template from pyecharts import options as opts from pyecharts.charts import Line app = Flask(__name__, static_folder="templates") app.config['MYSQL_HOST'] = 'localhost' # MySQL 主机名 app.config['MYSQL_USER'] = 'root' # MySQL 用户名 app.config['MYSQL_PASSWORD'] = '123123' # MySQL 密码 app.config['MYSQL_DB'] = 'csi' # MySQL 数据库名 def get_db_connection(): connection = mysql.connector.connect( host=app.config['MYSQL_HOST'], user=app.config['MYSQL_USER'], password=app.config['MYSQL_PASSWORD'], database=app.config['MYSQL_DB'], ) return connection # 返回的是数据库链接对象 def Line_base(index) -> Line: # index = int(index) # path = r'csi9.dat' # bf = read_bf_file_new(path,index) # csi_list = list(map(get_scale_csi, bf)) # print("test") # print(csi_list) # csi_np = (np.array(csi_list)) # csi_amp = np.abs(csi_np) # csi_total = numpy.empty(csi_amp[:, 0, 0, 25].shape) # csi_total_a = numpy.empty(csi_amp[:, 0, 0, 25].shape) # for i in range(6): # csi_total = csi_total + csi_amp[:, 0, 0, i + 15] # csi_total = csi_amp[:, 0, 0, 15] # csi_total_a = kalman_filter1(csi_amp[:, 0, 0, 15]) global_data.clear() for i in range(51): global_data.append(global_queue.get()) # print(global_data) csi_total_a = kalman_filter1(global_data) csi_total_a = csi_total_a[3:51] list2 = [str(i) for i in range(0, 48)] c = ( Line() .add_xaxis(list2) # .add_yaxis("波形1", csi_total[0:50],is_smooth='spline',is_symbol_show=False,color='blue') .add_yaxis("波形1", csi_total_a[0:48], is_smooth='spline', is_symbol_show=False, color='blue') .set_global_opts(title_opts=opts.TitleOpts(title="入侵检测系统", subtitle="实时波形检测"), yaxis_opts=opts.AxisOpts(max_=80, min_=0) ) ) return c @app.route("/") def index(): return render_template("index.html") @app.route("/LineChart") def get_Line_chart(): index = request.args.get('index') c = Line_base(index) return c.dump_options_with_quotes() @app.route("/getCount") def getCountAndIn(): index = request.args.get("index2") # print(index) state = getCountAndIN(index) # 返回一个包含入侵事件计数的JSON响应 return jsonify({'count': state}) @app.route('/get_alarm_history', methods=['GET']) def get_alarm_history(): try: connection = get_db_connection() cursor = connection.cursor() cursor.execute("SELECT date, type, description FROM alarm_history ORDER BY date DESC") history_data = cursor.fetchall() cursor.close() return jsonify({'data1': history_data}) except Exception as e: return jsonify({'error': str(e)}) import matplotlib.pyplot as plt import numpy import threading from wifilib import * from kalman5 import * from fancha import * import time import smtplib from email.mime.text import MIMEText from email.utils import formataddr plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False my_sender = '3284306656@qq.com' # 发件人邮箱账号 my_pass = 'bmjvijanuogzchbc' # 发件人邮箱授权码 my_user = '3377646378@qq.com' # 收件人邮箱账号,我这边发送给自己 def mail(): ret = True try: msg = MIMEText('有人入侵请注意!!!!!!', 'plain', 'utf-8') msg['From'] = formataddr(["XXX", my_sender]) msg['To'] = formataddr(["XXX", my_user]) msg['Subject'] = "测试报告" server = smtplib.SMTP_SSL("smtp.qq.com", 465) # 发件人邮箱中的SMTP服务器,端口是25 server.login(my_sender, my_pass) server.sendmail(my_sender, [my_user, ], msg.as_string()) # server.quit() except Exception: ret = False # print(1) # global_data def getCountAndIN(offset): # path = r'csi8.dat' # offset = int(offset) # date = numpy.empty([1, 7]) # bf = read_bf_file_new2(path, offset) # csi_list = list(map(get_scale_csi, bf)) # csi_np = (np.array(csi_list)) # csi_amp = np.abs(csi_np) # csi_total = numpy.empty(csi_amp[:, 0, 0, 8].shape) # for i in range(6): # csi_total = csi_total + csi_amp[:, 0, 0, i] # date = kalman_filter1(csi_amp[:, 0, 0, 8]) # print("test_data",date) data = kalman_filter1(global_data) data=data[3:50] # print(data) print(dynamic_variance1(data)) if detect_intrusion(dynamic_variance1(data)) == "intrusion": intrusion_date = datetime.now() intrusion_type = "无源入侵" intrusion_description = "有人入侵您的家" connection = get_db_connection() cursor = connection.cursor() sql = "INSERT INTO alarm_history (date, type, description) VALUES (%s, %s, %s)" cursor.execute(sql, (intrusion_date, intrusion_type, intrusion_description)) connection.commit() cursor.close() connection.close() threading.Thread(target=mail()).start() ##邮箱及授权码请自行配置,在SendMail下 return "intrusion" else: return "nobody" def get_csi_data(port): print("多线程1运行中…………") ser = serial.Serial(port=port, baudrate=921600, bytesize=8, parity='N', stopbits=1, timeout=0.1) pattern = r"\"\[(-?\d+,-?\d+)(,\s*-?\d+,-?\d+)*\]\"" while True: if ser.in_waiting > 0: data = ser.readline().decode('utf-8').strip() match = re.search(pattern, data) if match: str_data = match.group(0) # 提取整个匹配项,包括引号 # list_data = str_data[1:-1] # 去掉外面的引号 data_string = str_data[2:-2] # 使用split方法按逗号分割字符串,并使用列表推导式将每个字符串转换为整数 numbers_list = [int(num) for num in data_string.split(',')] tmp_results = [] for i, j in zip(numbers_list[2::2], numbers_list[3::2]): # 将数据添加到结果列表,63个 tmp_results.append(math.sqrt(i * i + j * j)) global_queue.put(variance(tmp_results)) # print(variance(tmp_results)) def variance(list): avg = sum(list) / len(list) sum_number = 0 for i in list: sum_number += (i - avg) ** 2 return round(sum_number / len(list)) # def get_data(): # print("多线程2运行中…………") # while(global_queue.qsize()>=50): # global_data.clear() # for i in range(51): # global_data.append(global_queue.get()) port = "COM3" th1 = Thread(target=get_csi_data, args=(port,)) th1.start() if __name__ == "__main__": try: # th1 = Thread(target=get_csi_data, args=(port,)) # th1.start() app.run() except Exception: input("输入任意字符串结束") th1.join() 解释这串python代码
06-12
#ifndef ARS_RADAR_H_ #define ARS_RADAR_H_ #include <ros/ros.h> #include <string> #include <vector> #include <thread> //#include"gps_msgs/gpsUtm.h" #include <can_msgs/Object.h> #include <can_msgs/ObjectArray.h> #include <can_msgs/FrameArray.h> #include <jsk_recognition_msgs/BoundingBox.h> #include <jsk_recognition_msgs/BoundingBoxArray.h> #include <pcl/point_cloud.h> #include <pcl_conversions/pcl_conversions.h> #include <sensor_msgs/PointCloud2.h> #include <diagnostic_msgs/DiagnosticStatus.h> #include <cmath> #include <unordered_map> class ArsRadar { public: ArsRadar(); ~ArsRadar(){ pthread_rwlock_destroy(&egoSpeedLock); pthread_rwlock_destroy(&countLock); }; bool init(); void run(); private: void sendMsgToArs(const ros::TimerEvent&); void configArs(const ros::TimerEvent&); void canMsg_callback(const can_msgs::FrameArray::ConstPtr& msg); //void gps_callback(const gps_msgs::gpsUtm::ConstPtr& msg); void parse_msg(const can_msgs::Frame &frame, int index, int n); void pubBoundingBoxArray(); enum Cluster_DynProp { Target_Move = 0, //移动 Target_Static = 1, //静止 Target_Come = 2, //来向 Target_May_Static = 3, //可能静止 Target_Unknow = 4, //未知 Target_Across = 5, //横穿 Target_Across_Static = 6, //横穿静止 Target_Stop = 7 //停止 }; typedef struct _Info { std::string type; uint8_t r; uint8_t g; uint8_t b; _Info(const std::string& t, uint8_t _r, uint8_t _g, uint8_t _b) { type = t; r = _r; g = _g; b = _b; } }Info; std::vector<Info> Infos; private: ros::Subscriber sub_can_; // 订阅can分析仪消息 ros::Subscriber sub_gps_; ros::Publisher pub_can_; // 向can分析仪发布消息 ros::Publisher pub_can_config; // 向can分析仪发布配置消息 ros::Publisher pub_object_; // 发布离我最近的障碍物消息 ros::Publisher pub_objects_; // 发布所有障碍物消息 ros::Publisher pub_cloud_; // 发布点云消息 pcl::PointCloud<pcl::PointXYZRGB> cloud; pcl::PointXYZRGB point; sensor_msgs::PointCloud
03-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值