当前位置: 首页 > article >正文

6、linux c 线程 -下

1. 线程的取消

意义

随时终止一个线程的执行。

函数

#include <pthread.h>
​
int pthread_cancel(pthread_t thread);
  • pthread_t thread:要取消的线程 ID。

返回值

  • 成功时返回 0。

  • 失败时返回非零错误码。

注意

线程的取消需要有取消点,取消点通常是阻塞的系统调用。线程在取消点处才会响应取消请求。

示例代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
​
// 线程执行函数
void *thread_function(void *arg) {while (1) {printf("Thread is running, TID: %lu\n", pthread_self());sleep(1);}return NULL;
}
​
int main() {pthread_t tid;pthread_create(&tid, NULL, thread_function, NULL);printf("Main process, PID: %d\n", getpid());sleep(2);pthread_cancel(tid);printf("Thread canceled\n");return 0;
}

手动设置取消点

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
​
// 线程执行函数
void *thread_function(void *arg) {while (1) {printf("Thread is running, TID: %lu\n", pthread_self());sleep(1);pthread_testcancel(); // 手动设置取消点}return NULL;
}
​
int main() {pthread_t tid;pthread_create(&tid, NULL, thread_function, NULL);printf("Main process, PID: %d\n", getpid());sleep(2);pthread_cancel(tid);printf("Thread canceled\n");return 0;
}

设置取消使能或禁止

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
​
// 线程执行函数
void *thread_function(void *arg) {int oldstate;pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);while (1) {printf("Thread is running, TID: %lu\n", pthread_self());sleep(1);}pthread_setcancelstate(oldstate, NULL);return NULL;
}
​
int main() {pthread_t tid;pthread_create(&tid, NULL, thread_function, NULL);printf("Main process, PID: %d\n", getpid());sleep(2);pthread_cancel(tid);printf("Thread canceled\n");return 0;
}

设置取消类型

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
​
// 线程执行函数
void *thread_function(void *arg) {int oldtype;pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);while (1) {printf("Thread is running, TID: %lu\n", pthread_self());sleep(1);}pthread_setcanceltype(oldtype, NULL);return NULL;
}
​
int main() {pthread_t tid;pthread_create(&tid, NULL, thread_function, NULL);printf("Main process, PID: %d\n", getpid());sleep(2);pthread_cancel(tid);printf("Thread canceled\n");return 0;
}

2. 运行段错误调试

可以使用 gdb 调试。

gdb ./yourapp
(gdb) run
# 等待出现 Thread 1 "pcancel" received signal SIGSEGV, Segmentation fault.
(gdb) bt

示例代码

#include <stdio.h>
​
int main() {int *ptr = NULL;*ptr = 10; // 会导致段错误return 0;
}

3. 线程的清理

必要性

当线程非正常终止时,需要清理一些资源,如释放内存、关闭文件等。

函数

#include <pthread.h>
​
void pthread_cleanup_push(void (*routine) (void *), void *arg)
void pthread_cleanup_pop(int execute)
  • pthread_cleanup_push:注册一个清理函数,在线程退出时自动调用。

  • pthread_cleanup_pop:取消注册一个清理函数。如果 execute 为非零值,则立即执行清理函数。

示例代码

#include <stdio.h>
#include <pthread.h>// 清理函数
void cleanup_function(void *arg) {printf("Cleanup function called, arg: %s\n", (char *)arg);
}// 线程执行函数
void *thread_function(void *arg) {pthread_cleanup_push(cleanup_function, "cleanup argument");printf("Thread is running, TID: %lu\n", pthread_self());sleep(2);pthread_exit(NULL);pthread_cleanup_pop(0);return NULL;
}int main() {pthread_t tid;pthread_create(&tid, NULL, thread_function, NULL);printf("Main process, PID: %d\n", getpid());sleep(3);return 0;
}

4. 线程的互斥和同步

临界资源概念

不能同时被多个线程访问的资源,例如写文件、打印机等。同一时间只能有一个线程访问。

必要性

防止多个线程同时访问临界资源导致数据不一致或资源竞争。

man 手册找不到 pthread_mutex_xxxxxxx 的解决方法

apt-get install manpages-posix-dev

5.互斥锁的创建和销毁

动态方式
#include <pthread.h>int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
  • pthread_mutex_t *restrict mutex:指向互斥锁的指针。

  • const pthread_mutexattr_t *restrict attr:互斥锁属性指针,通常传 NULL 使用默认属性。

静态方式
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
锁的销毁
#include <pthread.h>int pthread_mutex_destroy(pthread_mutex_t *mutex);

互斥锁的使用

#include <pthread.h>int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
  • pthread_mutex_lock:尝试加锁,如果锁已被占用,则阻塞等待。

  • pthread_mutex_unlock:释放锁。

  • pthread_mutex_trylock:尝试加锁,如果锁已被占用,则立即返回。

示例代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t mutex;// 线程执行函数
void *thread_function(void *arg) {pthread_mutex_lock(&mutex);printf("Thread is running, TID: %lu\n", pthread_self());sleep(2);pthread_mutex_unlock(&mutex);return NULL;
}int main() {pthread_mutex_init(&mutex, NULL);pthread_t tid1, tid2;pthread_create(&tid1, NULL, thread_function, NULL);pthread_create(&tid2, NULL, thread_function, NULL);printf("Main process, PID: %d\n", getpid());sleep(3);pthread_mutex_destroy(&mutex);return 0;
}

6. 读写锁

必要性

提高线程执行效率,允许多个线程同时读取资源,但写操作需要独占。

特性

  • 写者使用写锁,如果当前没有读者或写者,写者立即获得写锁;否则写者等待。

  • 读者使用读锁,如果当前没有写者,读者立即获得读锁;否则读者等待。

  • 同一时刻只有一个线程可以获得写锁,但可以有多个线程获得读锁。

  • 读写锁在写锁状态时,所有试图加锁的线程都会被阻塞。

  • 读写锁在读锁状态时,如果有写者试图加写锁,之后的其他线程的读锁请求会被阻塞。

函数

#include <pthread.h>int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

示例代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_rwlock_t rwlock;// 读线程执行函数
void *reader_function(void *arg) {pthread_rwlock_rdlock(&rwlock);printf("Reader is running, TID: %lu\n", pthread_self());sleep(2);pthread_rwlock_unlock(&rwlock);return NULL;
}// 写线程执行函数
void *writer_function(void *arg) {pthread_rwlock_wrlock(&rwlock);printf("Writer is running, TID: %lu\n", pthread_self());sleep(2);pthread_rwlock_unlock(&rwlock);return NULL;
}int main() {pthread_rwlock_init(&rwlock, NULL);pthread_t tid1, tid2, tid3, tid4;pthread_create(&tid1, NULL, reader_function, NULL);pthread_create(&tid2, NULL, reader_function, NULL);pthread_create(&tid3, NULL, writer_function, NULL);pthread_create(&tid4, NULL, writer_function, NULL);printf("Main process, PID: %d\n", getpid());sleep(3);pthread_rwlock_destroy(&rwlock);return 0;
}

7. 死锁

概念

两个或多个线程互相等待对方释放资源,导致无法继续执行。

避免方法

  1. 尽量减少锁的使用,最好使用一把锁。

  2. 调整锁的获取顺序,确保所有线程按相同顺序获取锁。

示例代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t mutex1, mutex2;// 线程1执行函数
void *thread1_function(void *arg) {pthread_mutex_lock(&mutex1);printf("Thread1 locked mutex1\n");sleep(1);pthread_mutex_lock(&mutex2);printf("Thread1 locked mutex2\n");pthread_mutex_unlock(&mutex2);pthread_mutex_unlock(&mutex1);return NULL;
}// 线程2执行函数
void *thread2_function(void *arg) {pthread_mutex_lock(&mutex2);printf("Thread2 locked mutex2\n");sleep(1);pthread_mutex_lock(&mutex1);printf("Thread2 locked mutex1\n");pthread_mutex_unlock(&mutex1);pthread_mutex_unlock(&mutex2);return NULL;
}int main() {pthread_mutex_init(&mutex1, NULL);pthread_mutex_init(&mutex2, NULL);pthread_t tid1, tid2;pthread_create(&tid1, NULL, thread1_function, NULL);pthread_create(&tid2, NULL, thread2_function, NULL);printf("Main process, PID: %d\n", getpid());sleep(3);pthread_mutex_destroy(&mutex1);pthread_mutex_destroy(&mutex2);return 0;
}

避免死锁的示例代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t mutex1, mutex2;// 线程1执行函数
void *thread1_function(void *arg) {pthread_mutex_lock(&mutex1);printf("Thread1 locked mutex1\n");sleep(1);pthread_mutex_lock(&mutex2);printf("Thread1 locked mutex2\n");pthread_mutex_unlock(&mutex2);pthread_mutex_unlock(&mutex1);return NULL;
}// 线程2执行函数
void *thread2_function(void *arg) {pthread_mutex_lock(&mutex1);printf("Thread2 locked mutex1\n");sleep(1);pthread_mutex_lock(&mutex2);printf("Thread2 locked mutex2\n");pthread_mutex_unlock(&mutex2);pthread_mutex_unlock(&mutex1);return NULL;
}int main() {pthread_mutex_init(&mutex1, NULL);pthread_mutex_init(&mutex2, NULL);pthread_t tid1, tid2;pthread_create(&tid1, NULL, thread1_function, NULL);pthread_create(&tid2, NULL, thread2_function, NULL);printf("Main process, PID: %d\n", getpid());sleep(3);pthread_mutex_destroy(&mutex1);pthread_mutex_destroy(&mutex2);return 0;
}

8、条件变量

应用场景

生产者消费者问题,是线程同步的一种手段。

必要性

为了实现等待某个资源,让线程休眠。提高运行效率。

函数说明

#include <pthread.h>// 等待条件变量,会自动释放互斥锁,等待被唤醒
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);// 等待条件变量,会自动释放互斥锁,等待被唤醒,超时则返回
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);// 唤醒一个等待的线程
int pthread_cond_signal(pthread_cond_t *cond);// 唤醒所有等待的线程
int pthread_cond_broadcast(pthread_cond_t *cond);

使用步骤

1. 初始化
  • 静态初始化:

    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;      // 初始化条件变量
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  // 初始化互斥量
    
  • 动态初始化:

    pthread_cond_init(&cond, NULL);
    
2. 生产资源线程
pthread_mutex_lock(&mutex);
// 开始产生资源
pthread_cond_signal(&cond);    // 通知一个消费线程
// 或者
pthread_cond_broadcast(&cond); // 广播通知多个消费线程
pthread_mutex_unlock(&mutex);
3. 消费者线程
pthread_mutex_lock(&mutex);
while (/* 没有资源 */) {   // 防止惊群效应pthread_cond_wait(&cond, &mutex); 
}
// 有资源了,消费资源
pthread_mutex_unlock(&mutex);

注意事项

  1. pthread_cond_wait(&cond, &mutex),在没有资源等待时是先 unlock 休眠,等资源到了,再 lock。所以 pthread_cond_waitpthread_mutex_lock 必须配对使用。

  2. 如果 pthread_cond_signal 或者 pthread_cond_broadcast 早于 pthread_cond_wait,则有可能会丢失信号。

  3. pthread_cond_broadcast 信号会被多个线程收到,这叫线程的惊群效应。所以需要加上判断条件 while 循环。

示例代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int resource_ready = 0;// 生产者线程
void *producer(void *arg) {printf("Producer: Producing resource...\n");sleep(1);pthread_mutex_lock(&mutex);resource_ready = 1;printf("Producer: Resource is ready\n");pthread_cond_signal(&cond); // 唤醒消费者线程pthread_mutex_unlock(&mutex);return NULL;
}// 消费者线程
void *consumer(void *arg) {printf("Consumer: Waiting for resource...\n");pthread_mutex_lock(&mutex);while (!resource_ready) { // 防止惊群效应pthread_cond_wait(&cond, &mutex);}printf("Consumer: Resource consumed\n");pthread_mutex_unlock(&mutex);return NULL;
}int main() {pthread_t prod_tid, cons_tid;pthread_create(&prod_tid, NULL, producer, NULL);pthread_create(&cons_tid, NULL, consumer, NULL);pthread_join(prod_tid, NULL);pthread_join(cons_tid, NULL);return 0;
}

9、线程池概念和使用

概念

通俗的讲就是一个线程的池子,可以循环的完成任务的一组线程集合。

必要性

我们平时创建一个线程,完成某一个任务,等待线程的退出。但当需要创建大量的线程时,假设 T1 为创建线程时间,T2 为在线程任务执行时间,T3 为线程销毁时间,当 T1+T3 > T2,这时候就不划算了,使用线程池可以降低频繁创建和销毁线程所带来的开销,任务处理时间比较短的时候这个好处非常显著。

线程池的基本结构

  1. 任务队列,存储需要处理的任务,由工作线程来处理这些任务。

  2. 线程池工作线程,它是任务队列任务的消费者,等待新任务的信号。

线程池的实现

1. 创建线程池的基本结构
typedef struct Task {void (*func)(void *arg);void *arg;struct Task *next;
} Task;typedef struct ThreadPool {pthread_mutex_t lock;pthread_cond_t cond;Task *head;Task *tail;int thread_count;int queue_size;int shutdown;
} ThreadPool;
2. 线程池的初始化
ThreadPool *pool_init(int thread_count) {ThreadPool *pool = (ThreadPool *)malloc(sizeof(ThreadPool));pool->lock = PTHREAD_MUTEX_INITIALIZER;pool->cond = PTHREAD_COND_INITIALIZER;pool->head = NULL;pool->tail = NULL;pool->thread_count = thread_count;pool->queue_size = 0;pool->shutdown = 0;for (int i = 0; i < thread_count; i++) {pthread_t tid;pthread_create(&tid, NULL, worker, pool);}return pool;
}
3. 线程池添加任务
void pool_add_task(ThreadPool *pool, void (*func)(void *arg), void *arg) {pthread_mutex_lock(&pool->lock);Task *task = (Task *)malloc(sizeof(Task));task->func = func;task->arg = arg;task->next = NULL;if (pool->tail == NULL) {pool->head = pool->tail = task;} else {pool->tail->next = task;pool->tail = task;}pool->queue_size++;pthread_cond_signal(&pool->cond);pthread_mutex_unlock(&pool->lock);
}
4. 实现工作线程
void *worker(void *arg) {ThreadPool *pool = (ThreadPool *)arg;while (1) {pthread_mutex_lock(&pool->lock);while (pool->head == NULL && !pool->shutdown) {pthread_cond_wait(&pool->cond, &pool->lock);}if (pool->shutdown) {pthread_mutex_unlock(&pool->lock);break;}Task *task = pool->head;pool->head = task->next;if (pool->head == NULL) {pool->tail = NULL;}pool->queue_size--;pthread_mutex_unlock(&pool->lock);task->func(task->arg);free(task);}return NULL;
}
5. 线程池的销毁
void pool_destroy(ThreadPool *pool) {pthread_mutex_lock(&pool->lock);pool->shutdown = 1;pthread_cond_broadcast(&pool->cond);pthread_mutex_unlock(&pool->lock);for (int i = 0; i < pool->thread_count; i++) {pthread_join(pthread_self(), NULL);}while (pool->head != NULL) {Task *task = pool->head;pool->head = task->next;free(task);}pthread_mutex_destroy(&pool->lock);pthread_cond_destroy(&pool->cond);free(pool);
}

示例代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>// 任务函数
void task_function(void *arg) {printf("Task is running, arg: %s\n", (char *)arg);sleep(1);
}int main() {ThreadPool *pool = pool_init(4);pool_add_task(pool, task_function, "task1");pool_add_task(pool, task_function, "task2");pool_add_task(pool, task_function, "task3");pool_destroy(pool);return 0;
}

###

相关文章:

6、linux c 线程 -下

1. 线程的取消 意义 随时终止一个线程的执行。 函数 #include <pthread.h> ​ int pthread_cancel(pthread_t thread); pthread_t thread&#xff1a;要取消的线程 ID。 返回值 成功时返回 0。 失败时返回非零错误码。 注意 线程的取消需要有取消点&#xff0c…...

分布式算法:Paxos Raft 两种共识算法

1. Paxos算法 Paxos算法是 Leslie Lamport&#xff08;莱斯利兰伯特&#xff09;在 1990 年提出的一种分布式系统共识算法。也是第一个被证明完备的共识算法&#xff08;前提是不存在恶意节点&#xff09;。 1.1 简介 Paxos算法是第一个被证明完备的分布式系统共识算法。共识…...

什么是数据库监控

数据库监控是一个综合的过程&#xff0c;涉及观察、分析和优化组织内数据库的性能、运行状况和可用性。通过持续跟踪查询执行时间、CPU使用率、内存消耗和存储I/O等指标&#xff0c;数据库监控使管理员能够主动识别和解决潜在问题。这种对数据库操作的实时可见性对于确保应用程…...

Java学习总结-泛型

什么是泛型&#xff1f; 定义 类、接口、方法时&#xff0c;同时声明了一个或多个类型变量&#xff08;如&#xff1a;<E>&#xff09;&#xff0c;称为泛型类、泛型接口、泛型方法、他们统称为泛型。public class ArrayList<E>{ }。 有什么作用呢&#xf…...

基于深度学习的相位调制算法步骤

1.构建网络结构 2.制作数据集 3.训练网络 4.引入评价指标 5.迭代优化 总结 通过以上步骤&#xff0c;可以实现基于深度学习的相位调制算法&#xff1a; 使用 U-Net 构建神经网络。 生成数据集并训练网络。 使用训练好的网络预测相位分布。 通过相关系数 γ 评估调制效果&…...

curl使用报错error LNK2001: 无法解析的外部符号 __imp__CertCloseStore@8

使用curl静态库libcurl_a.lib 时报错&#xff0c;内容如下&#xff1a; 1>libcurl_a.lib(openssl.obj) : error LNK2001: 无法解析的外部符号 __imp__CertCloseStore8 1>libcrypto.lib(libcrypto-lib-e_capi.obj) : error LNK2001: 无法解析的外部符号 __imp__CertClose…...

Go语言的基础类型

一基础数据类型 一、布尔型&#xff08;Bool&#xff09; 定义&#xff1a;表示逻辑真 / 假&#xff0c;仅有两个值&#xff1a;true 和 false内存占用&#xff1a;1 字节使用场景&#xff1a;条件判断、逻辑运算 二、数值型&#xff08;Numeric&#xff09; 1. 整数类型&…...

动力保护板测试仪:电池安全的坚实守护者

在新能源技术日新月异的今天&#xff0c;电池作为各类电子设备的心脏&#xff0c;其安全性与可靠性成为了行业内外关注的焦点。而动力保护板&#xff0c;作为电池系统中的重要组成部分&#xff0c;承担着精准调控电池充放电、防止电池过充、过放、短路等危险情况的重任。然而&a…...

Lineageos 22.1(Android 15)制定应用强制横屏

一、前言 有时候需要系统的某个应用强制衡平显示&#xff0c;不管他是如何配置的。我们只需要简单的拿到top的Task下面的ActivityRecord&#xff0c;并判断包名来强制实现。 二、调整wms com.android.server.wm.DisplayRotation /*** Given an orientation constant, return…...

【Python】【PyQt5】设置事件绑定(例为按钮点击显示提示框)

前言 上篇文章我们讲了如何创作一个UI界面&#xff0c;并将其使用代码显示出来&#xff0c;这篇文章我们来讲讲事件的绑定 为增加文章趣味性&#xff0c;此篇文章我们将以点击窗口中的按钮来后并显示一个提示框 修改上次代码&#xff08;优化&#xff09; 上篇文章我所讲的要…...

node-ddk, electron组件, 自定义本地文件协议,打开本地文件

node-ddk 文件协议 https://blog.csdn.net/eli960/article/details/146207062 也可以下载demo直接演示 http://linuxmail.cn/go#node-ddk 安全 考虑到安全, 本系统禁止使用 file:/// 在主窗口, 自定义文件协议,可以多个 import main, { NODEDDK } from "node-ddk/m…...

SpringBoot-3-JWT令牌

目录 引入 引入依赖 拦截器 创建工具类 创建拦截器的包及拦截器 注册拦截器 修改一下登录成功后token的代码 测试 引入 试想一下&#xff0c;以上我们的访问都是直接访问对应的接口。比如说用户登录的时候就访问登录的接口。 那么如果有人他不访问你的登录接口&#…...

ChatGPT vs DeepSeek vs Copilot vs Claude:谁将问鼎AI王座?

李升伟 整理 2025年的人工智能领域创新涌动&#xff0c;ChatGPT、DeepSeek、Copilot和Claude四大模型各领风骚。这些AI系统各具特色&#xff0c;分别专注于编程、创意写作、技术推理和AI伦理等不同领域。本文将深入解析这些AI模型的功能特性及其优势领域。 核心AI模型解析 C…...

git使用经验(一)

git使用经验&#xff08;一&#xff09; 我之前已经下载了别人的代码&#xff0c;我想在此基础上进行修改&#xff0c;并移动到自己的私有仓库&#xff0c;方便上传到自己的私有仓库自己进行版本控制 git clone下来别人的代码&#xff0c;删除有关git的隐藏文件 进入到自己的…...

文件上传的小点总结

1.文件上传漏洞 服务器端脚本语言对上传文件没有严格的验证和过滤&#xff0c;就可以给攻击者上传恶意脚本文件的可能。 文件上传检测绕过&#xff1a; 简单思路&#xff1a;&#xff08;这里以前端上传图片为例&#xff09; ①开启phpstudy&#xff0c;启动apache即可&…...

基于WebRtc,GB28181,Rtsp/Rtmp,SIP,JT1078,H265/WEB融合视频会议接入方案

智能融合视频会议系统方案—多协议、多场景、全兼容的一站式视频协作平台 OvMeet,LiveMeet针对用户​核心痛点实现功能与用户价值 &#xff0c;Web平台实现MCU多协议&#xff0c;H265/H264等不同编码监控&#xff0c;直播&#xff0c;会议&#xff0c;调度资源统一融合在一套界…...

Python常用库全解析:从数据处理到机器学习

适合人群&#xff1a;Python初学者 | 数据分析师 | 机器学习爱好者 目录 一、NumPy&#xff1a;科学计算的核心库 1. 核心功能 2. 应用领域 3. 常用方法示例 二、Pandas&#xff1a;数据分析的瑞士军刀 1. 核心功能 2. 应用领域 3. 常用方法示例 三、Matplotlib&#…...

基于漂浮式海上风电场系统的浮式风力发电机matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于漂浮式海上风电场系统的浮式风力发电机matlab仿真&#xff0c;通过MATLAB数值仿真对浮式风力发电机的性能做模拟与仿真。 2.系统仿真结果 3.核心程序与模型 版本&#x…...

深入探索ArkUI中的@LocalBuilder装饰器:构建高效可维护的UI组件

在ArkUI框架中&#xff0c;组件化开发是提升代码复用性和维护性的关键手段。随着项目复杂度的增加&#xff0c;开发者常常面临如何在保持组件封装性的同时&#xff0c;灵活处理组件内部逻辑的问题。传统的Builder装饰器虽然提供了强大的自定义构建能力&#xff0c;但在某些场景…...

【QA】外观模式在Qt中有哪些应用?

1. QWidget及其布局管理系统 外观模式体现 QWidget 是Qt中所有用户界面对象的基类&#xff0c;而布局管理系统&#xff08;如 QVBoxLayout、QHBoxLayout、QGridLayout 等&#xff09;就像是一个外观类。客户端代码&#xff08;开发者编写的界面代码&#xff09;通常不需要直接…...

在ASP.NET Core中使用NLog:配置与性能优化指南

在ASP.NET Core中使用NLog&#xff1a;配置与性能优化指南 在ASP.NET Core中使用NLog&#xff1a;配置与性能优化指南1. 安装NLog包2. 基础配置2.1 创建nlog.config文件2.2 程序启动配置 3. 在代码中使用日志4. 性能优化配置4.1 异步日志处理4.2 自动清理旧日志4.3 缓冲写入优化…...

yaffs

YAFFS&#xff08;Yet Another Flash File System&#xff09;是专为NAND闪存设计的日志结构文件系统&#xff0c;其核心原理围绕NAND闪存的特性优化数据管理。以下是其关键原理的详细说明&#xff1a; 1. NAND闪存适配 写入限制&#xff1a;NAND闪存需按页写入&#xff08;通…...

快速查询手机是否处于联网状态?

手机是否处于联网状态对于我们日常生活中的沟通、工作和娱乐都至关重要。有时候我们需要迅速了解一个手机号码的在网状态&#xff0c;例如是正常使用、停机、不在网等。而要实现这一功能&#xff0c;我们可以利用挖数据平台提供的在线查询工具&#xff0c;通过API接口来查询手机…...

使用 .NET Core 的本地 DeepSeek-R1

使用 .NET 在我的 MacBook Pro 上与当地 LLM 聊天的历程。 如今&#xff0c;只需使用浏览器即可轻松使用 ChatGPT 或其他 genAI。作为开发人员&#xff0c;我们可以通过直接集成 OpenAI API 等来做更复杂的事情。如果我们想在自己的机器上运行 LLM&#xff0c;只是为了找人聊天…...

LeetCode 206 Reverse Linked List 反转链表 Java

举例1&#xff1a; 输入&#xff1a; [1,2,3,4,5]&#xff0c; 输出&#xff1a; [5,4,3,2,1]. 举例2&#xff1a; 输入&#xff1a; [] 输出&#xff1a;[] 思路&#xff1a;方法有三种&#xff0c;分别是递归&#xff0c;栈&#xff0c;双指针&#xff0c;本篇使用栈&a…...

SQL Server查询计划操作符(7.3)——查询计划相关操作符(11)

7.3. 查询计划相关操作符 98&#xff09;Table Scan&#xff1a;该操作符从查询计划参数列确定的表中获取所有数据行。如果其参数列中出现WHERE:()谓词&#xff0c;则只返回满足该谓词的数据行。该操作符为逻辑操作符和物理操作符。该操作符具体如图7.3-98节点1所示。 图 7.3-…...

xy轴不等比缩放问题——AUTOCAD c#二次开发

在 AutoCAD .net api里&#xff0c;部分实体&#xff0c;像文字、属性、插入块等&#xff0c;是不支持非等比缩放的。 如需对AutoCAD中图形进行xyz方向不等比缩放&#xff0c;则需进行额外的函数封装。 选择图元&#xff0c;指定缩放基准点&#xff0c;scaleX 0.5, scaleY …...

【原创首发】开源基于AT32 SIP/VOIP电话

前言 本次为了反馈各位粉丝的关注&#xff0c;特此分享 AT32_VOIP 工程&#xff0c;此功能其实跟我之前发过的《STM32F429的VOIP功能》是一样的&#xff0c;只是用了AT32F437。 其实那个工程是一个比较Demo中的Demo&#xff0c;很多功能和硬件依赖性太大了。后面项目中发现AT…...

本地部署 LangManus

本地部署 LangManus 0. 引言1. 部署 LangManus2. 部署 LangManus Web UI 0. 引言 LangManus 是一个社区驱动的 AI 自动化框架&#xff0c;它建立在开源社区的卓越工作基础之上。我们的目标是将语言模型与专业工具&#xff08;如网络搜索、爬虫和 Python 代码执行&#xff09;相…...

一篇文章入门Python Flask框架前后端数据库开发实践(pycharm在anaconda环境下)

Python Flask 是一个轻量级的 Web 应用框架&#xff0c;也被称为微框架。它以简洁、灵活和易于上手的特点而受到开发者的喜爱。 核心特点 轻量级&#xff1a;Flask 核心代码简洁&#xff0c;仅包含 Web 开发的基本功能&#xff0c;不强制使用特定的数据库、模板引擎等&#xf…...