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

【0803作业】创建两个线程:其中一个线程拷贝图片的前半部分,另一个线程拷贝后半部分(4种方法)

方法一:使用pthread_create、pthread_exit、pthread_join函数【两个线程不共用同一份资源】

        先在主函数创建并清空拷贝的目标文件,再创建两个线程,在两个线程内部同时打开要读取的文件以及要拷贝的目标文件(两个线程不共用同一份资源)。

使用到的函数:

  1. 标准IO函数(fprintf)【用于打印错误信息】
  2. 文件IO函数(open、close、lseek)
  3. 有关线程的函数(pthread_create、pthread_exit、pthread_join)
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <head.h>
//线程的执行体
void* callback_1(void* arg)   //void* arg = (void*)&c
{umask(0);int fp_r=open("./1.png",O_RDONLY);                                               if(fp_r < 0){ERR_MSG("open");}int fp_w=open("./copy.png",O_WRONLY);if(fp_w <0){ERR_MSG("open");}char c = 0;off_t len=lseek(fp_r,0,SEEK_END);int i=0;lseek(fp_r,0,SEEK_SET);lseek(fp_w,0,SEEK_SET);for(i=0;i<len/2;i++){bzero(&c,sizeof(c));read(fp_r,&c,1);write(fp_w,&c,1);}close(fp_r);close(fp_w);printf("前半部分拷贝完毕\n");pthread_exit(NULL);
}
void* callback_2(void* arg)
{umask(0);int fp_r=open("./1.png",O_RDONLY);if(fp_r < 0){ERR_MSG("open");}int fp_w=open("./copy.png",O_WRONLY);if(fp_w < 0){ERR_MSG("open");}char c = 0;off_t len=lseek(fp_r,0,SEEK_END);int i=0;lseek(fp_r,len/2,SEEK_SET);lseek(fp_w,len/2,SEEK_SET);for(i=0;i<len/2;i++){bzero(&c,sizeof(c));read(fp_r,&c,sizeof(c));write(fp_w,&c,sizeof(c));}close(fp_r);close(fp_w);printf("后半部分拷贝完毕\n");pthread_exit(NULL);}
int main(int argc, const char *argv[])
{//两个线程在拷贝前,确保文件w存在,且是清空状态int fp_w=open("./copy.png",O_WRONLY|O_CREAT|O_TRUNC,0664);if(fp_w <0){ERR_MSG("open");}close(fp_w);pthread_t tid_1,tid_2;if(pthread_create(&tid_1,NULL,callback_1,NULL) != 0){fprintf(stderr, "pthread_create failed __%d__\n",__LINE__);return -1;}pthread_join(tid_1,NULL);if(pthread_create(&tid_2,NULL,callback_2,NULL)!=0){fprintf(stderr, "pthread_create failed __%d__\n",__LINE__);return -1;}pthread_join(tid_2,NULL);printf("主线程准备退出... ...\n");return 0;
}

方法二:使用结构体【两个线程共享同一份资源】

        创建一个结构体用于存放需要打开的两个文件文件标识符、需要拷贝的字节大小。

        在主函数中打开两个文件,计算好需要拷贝的字节大小,再创建两个线程,将结构体fileinfo的地址传递到线程中(强转成(void*)类型再传,否则报错),线程中用指针void* arg接fileinfo的地址。线程中需要将指针arg的地址转为struct Msg类型。

        PS:两个线程共享同一份资源,使用pthread_exit函数使线程1先完成拷贝(与sleep达到的效果一致)。

使用到的函数:

  1. 结构体struct
  2. 标准IO函数(fprintf)【用于打印错误信息】
  3. 文件IO函数(open、close、lseek)
  4. 有关线程的函数(pthread_create、pthread_exit、pthread_join)
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <head.h>
struct Msg
{int fp_r;int fp_w;off_t size;
};
//线程1的执行体:拷贝前半部分
void* callback_1(void* arg)   //void* arg = &fileinfo
{struct Msg *tp=(struct Msg*)arg;int fp_r=tp->fp_r;int fp_w=tp->fp_w;off_t size=tp->size;//将光标偏移到开头,拷贝size/2个字节到目标文件中lseek(fp_r,0,SEEK_SET);lseek(fp_w,0,SEEK_SET);char c = 0;for(int i=0;i<size/2;i++){bzero(&c,sizeof(c));read(fp_r,&c,1);write(fp_w,&c,1);}printf("前半部分拷贝完毕\n");pthread_exit(NULL);//退出分支线程
}
//线程2的执行体
void* callback_2(void* arg)  //void* arg = &fileinfo
{//sleep(5);//主动放弃cpu资源,让线程1先执行struct Msg *tp=(struct Msg*)arg;int fp_r=tp->fp_r;int fp_w=tp->fp_w;off_t size=tp->size;//将光标偏移到size/2的位置,拷贝size/2个字节到目标文件中lseek(fp_r,size/2,SEEK_SET);lseek(fp_w,size/2,SEEK_SET);char c = 0;for(int i=0;i<size/2;i++){bzero(&c,sizeof(c));read(fp_r,&c,sizeof(c));write(fp_w,&c,sizeof(c));}printf("后半部分拷贝完毕\n");pthread_exit(NULL);//退出分支线程
}
int main(int argc, const char *argv[])
{struct Msg fileinfo;//以读的方式打开1.pngfileinfo.fp_r=open("./1.png",O_RDONLY);if(fileinfo.fp_r < 0){ERR_MSG("open");return -1;}//以写的方式打开并创建(若存在则清空)copy.pngfileinfo.fp_w=open("./copy.png",O_WRONLY|O_CREAT|O_TRUNC,0664);if(fileinfo.fp_w <0){ERR_MSG("open");return -1;}//计算需要拷贝的字节大小fileinfo.size=lseek(fileinfo.fp_r,0,SEEK_END);//创建2个线程pthread_t tid_1,tid_2;if(pthread_create(&tid_1,NULL,callback_1,(void *)&fileinfo) != 0){fprintf(stderr, "pthread_create failed __%d__\n",__LINE__);return -1;}pthread_join(tid_1,NULL);//阻塞等待线程1完成if(pthread_create(&tid_2,NULL,callback_2,(void *)&fileinfo) !=0){fprintf(stderr, "pthread_create failed __%d__\n",__LINE__);return -1;}pthread_join(tid_2,NULL);//阻塞等待线程2完成//关闭文件close(fileinfo.fp_r);close(fileinfo.fp_w);printf("主线程准备退出\n");return 0;
}

方法三:互斥锁【两个线程共享同一份资源】

       创建一个结构体用于存放需要打开的两个文件文件标识符、需要拷贝的字节大小;将互斥锁初始化。

达到的效果:

  • 拷贝完前半部分或后半部分解锁

        PS:两个线程共享同一份资源,利用互斥锁完成任务。

使用到的函数:

  1. 结构体struct
  2. 标准IO函数(fprintf)【用于打印错误信息】
  3. 文件IO函数(open、close、lseek)
  4. 有关线程的函数(pthread_create、pthread_exit、pthread_join)
  5. 互斥锁(创建互斥锁pthread_mutex_init、上锁pthread_mutex_lock、解锁pthread_mutex_unlock、销毁互斥锁pthread_mutex_destroy)

修改后:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <head.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//临界资源
struct Msg
{int fp_r;int fp_w;off_t size;pthread_mutex_t mutex;//互斥锁
};
//线程1的执行体:拷贝前半部分
void* callback_1(void* arg)   //void* arg = &fileinfo
{struct Msg *fileinfo=(struct Msg*)arg;int fp_r=fileinfo->fp_r;int fp_w=fileinfo->fp_w;off_t size=fileinfo->size;char c = 0;/************************临界区***************************///上锁pthread_mutex_lock(&fileinfo->mutex);//将光标偏移到开头,拷贝size/2个字节到目标文件中lseek(fp_r,0,SEEK_SET);lseek(fp_w,0,SEEK_SET);for(int i=0;i<size/2;i++){//bzero(&c,sizeof(c));read(fp_r,&c,1);write(fp_w,&c,1);}printf("前半部分拷贝完毕\n");//解锁pthread_mutex_unlock(&fileinfo->mutex);/************************临界区***************************/pthread_exit(NULL);//退出分支线程
}
//线程2的执行体
void* callback_2(void* arg)  //void* arg = &fileinfo
{struct Msg *fileinfo=(struct Msg*)arg;int fp_r=fileinfo->fp_r;int fp_w=fileinfo->fp_w;off_t size=fileinfo->size;char c = 0;/************************临界区***************************///上锁pthread_mutex_lock(&fileinfo->mutex);//将光标偏移到size/2的位置,拷贝size/2个字节到目标文件中lseek(fp_r,size/2,SEEK_SET);lseek(fp_w,size/2,SEEK_SET);for(int i=0;i<size/2;i++){//bzero(&c,sizeof(c));read(fp_r,&c,1);write(fp_w,&c,1);}printf("后半部分拷贝完毕\n");//解锁pthread_mutex_unlock(&fileinfo->mutex);/************************临界区***************************/pthread_exit(NULL);//退出分支线程
}
int main(int argc, const char *argv[])
{struct Msg fileinfo;//以读的方式打开1.pngfileinfo.fp_r=open("./1.png",O_RDONLY);if(fileinfo.fp_r < 0){ERR_MSG("open");return -1;}//以写的方式打开并创建(若存在则清空)copy.pngfileinfo.fp_w=open("./copy.png",O_WRONLY|O_CREAT|O_TRUNC,0664);if(fileinfo.fp_w <0){ERR_MSG("open");return -1;}//计算需要拷贝的字节大小fileinfo.size=lseek(fileinfo.fp_r,0,SEEK_END);//申请一个互斥锁pthread_mutex_init(&fileinfo.mutex,NULL);//创建2个线程pthread_t tid_1,tid_2;if(pthread_create(&tid_1,NULL,callback_1,(void *)&fileinfo) != 0){fprintf(stderr, "pthread_create failed __%d__\n",__LINE__);return -1;}//pthread_detach(tid_1);  //分离线程1if(pthread_create(&tid_2,NULL,callback_2,(void *)&fileinfo) !=0){fprintf(stderr, "pthread_create failed __%d__\n",__LINE__);return -1;}pthread_join(tid_1,NULL);//阻塞等待线程1完成pthread_join(tid_2,NULL);//阻塞等待线程2完成//销毁互斥锁pthread_mutex_destroy(&fileinfo.mutex);//关闭文件close(fileinfo.fp_r);close(fileinfo.fp_w);printf("主线程准备退出\n");return 0;
}

错误:将线程1分离

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <head.h>
//临界资源
struct Msg
{int fp_r;int fp_w;off_t size;pthread_mutex_t mutex;//互斥锁
};
//线程1的执行体:拷贝前半部分
void* callback_1(void* arg)   //void* arg = &fileinfo
{struct Msg *fileinfo=(struct Msg*)arg;/************************临界区***************************///上锁pthread_mutex_lock(&fileinfo->mutex);int fp_r=fileinfo->fp_r;int fp_w=fileinfo->fp_w;off_t size=fileinfo->size;//将光标偏移到开头,拷贝size/2个字节到目标文件中lseek(fp_r,0,SEEK_SET);lseek(fp_w,0,SEEK_SET);char c = 0;for(int i=0;i<size/2;i++){bzero(&c,sizeof(c));read(fp_r,&c,1);write(fp_w,&c,1);}printf("前半部分拷贝完毕\n");//解锁pthread_mutex_unlock(&fileinfo->mutex);/************************临界区***************************/pthread_exit(NULL);//退出分支线程
}
//线程2的执行体
void* callback_2(void* arg)  //void* arg = &fileinfo
{struct Msg *fileinfo=(struct Msg*)arg;/************************临界区***************************///上锁pthread_mutex_lock(&fileinfo->mutex);int fp_r=fileinfo->fp_r;int fp_w=fileinfo->fp_w;off_t size=fileinfo->size;//将光标偏移到size/2的位置,拷贝size/2个字节到目标文件中lseek(fp_r,size/2,SEEK_SET);lseek(fp_w,size/2,SEEK_SET);char c = 0;for(int i=0;i<size/2;i++){bzero(&c,sizeof(c));read(fp_r,&c,sizeof(c));write(fp_w,&c,sizeof(c));}printf("后半部分拷贝完毕\n");//解锁pthread_mutex_unlock(&fileinfo->mutex);/************************临界区***************************/pthread_exit(NULL);//退出分支线程
}
int main(int argc, const char *argv[])
{struct Msg fileinfo;//以读的方式打开1.pngfileinfo.fp_r=open("./1.png",O_RDONLY);if(fileinfo.fp_r < 0){ERR_MSG("open");return -1;}//以写的方式打开并创建(若存在则清空)copy.pngfileinfo.fp_w=open("./copy.png",O_WRONLY|O_CREAT|O_TRUNC,0664);if(fileinfo.fp_w <0){ERR_MSG("open");return -1;}//计算需要拷贝的字节大小fileinfo.size=lseek(fileinfo.fp_r,0,SEEK_END);//申请一个互斥锁pthread_mutex_init(&fileinfo.mutex,NULL);//创建2个线程pthread_t tid_1,tid_2;if(pthread_create(&tid_1,NULL,callback_1,(void *)&fileinfo) != 0){fprintf(stderr, "pthread_create failed __%d__\n",__LINE__);return -1;}pthread_detach(tid_1);  //分离线程1if(pthread_create(&tid_2,NULL,callback_2,(void *)&fileinfo) !=0){fprintf(stderr, "pthread_create failed __%d__\n",__LINE__);return -1;}pthread_join(tid_2,NULL);//阻塞等待线程2完成//关闭文件close(fileinfo.fp_r);close(fileinfo.fp_w);printf("主线程准备退出\n");//销毁互斥锁pthread_mutex_destroy(&fileinfo.mutex);return 0;
}

方法四:互斥锁【两个线程共享同一份资源】

       创建一个结构体用于存放需要打开的两个文件文件标识符、需要拷贝的字节大小;将互斥锁初始化。

​​​​​​​达到的效果:

  • 记录拷贝的位置,给偏移量和offset上锁。记录完fooset的数据后解锁
  • 可两个线程切换拷贝

        PS:两个线程共享同一份资源,利用互斥锁完成任务。

使用到的函数:

  1. 结构体struct
  2. 标准IO函数(fprintf)【用于打印错误信息】
  3. 文件IO函数(open、close、lseek)
  4. 有关线程的函数(pthread_create、pthread_exit、pthread_join)
  5. 互斥锁(创建互斥锁pthread_mutex_init、上锁pthread_mutex_lock、解锁pthread_mutex_unlock、销毁互斥锁pthread_mutex_destroy)
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <head.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//临界资源
struct Msg
{int fp_r;int fp_w;off_t size;pthread_mutex_t mutex;//互斥锁
};
//线程1的执行体:拷贝前半部分
void* callback_1(void* arg)   //void* arg = &fileinfo
{struct Msg *fileinfo=(struct Msg*)arg;int fp_r=fileinfo->fp_r;int fp_w=fileinfo->fp_w;off_t size=fileinfo->size;char c = 0;off_t offset=0;for(int i=0;i<size/2;i++){/******************临界区*******************///上锁pthread_mutex_lock(&fileinfo->mutex);//将光标偏移到开头,拷贝size/2个字节到目标文件中lseek(fp_r,offset,SEEK_SET);lseek(fp_w,offset,SEEK_SET);read(fp_r,&c,1);write(fp_w,&c,1);offset=lseek(fp_r,0,SEEK_CUR);//解锁pthread_mutex_unlock(&fileinfo->mutex);/****** ************临界区*******************/}printf("前半部分拷贝完毕\n");pthread_exit(NULL);//退出分支线程
}
//线程2的执行体
void* callback_2(void* arg)  //void* arg = &fileinfo
{struct Msg *fileinfo=(struct Msg*)arg;int fp_r=fileinfo->fp_r;int fp_w=fileinfo->fp_w;off_t size=fileinfo->size;char c = 0;off_t offset=size/2;for(int i=0;i<size/2;i++){/*******************临界区*******************///上锁pthread_mutex_lock(&fileinfo->mutex);//将光标偏移到size/2的位置,拷贝size/2个字节到目标文件中lseek(fp_r,offset,SEEK_SET);lseek(fp_w,offset,SEEK_SET);read(fp_r,&c,1);write(fp_w,&c,1);offset=lseek(fp_r,0,SEEK_CUR);//解锁pthread_mutex_unlock(&fileinfo->mutex);                                                            /******************临界区*********************/}printf("后半部分拷贝完毕\n");pthread_exit(NULL);//退出分支线程
}
int main(int argc, const char *argv[])
{struct Msg fileinfo;//以读的方式打开1.pngfileinfo.fp_r=open("./1.png",O_RDONLY);if(fileinfo.fp_r < 0){ERR_MSG("open");return -1;}//以写的方式打开并创建(若存在则清空)copy.pngfileinfo.fp_w=open("./copy.png",O_WRONLY|O_CREAT|O_TRUNC,0664);if(fileinfo.fp_w <0){ERR_MSG("open");return -1;}//计算需要拷贝的字节大小fileinfo.size=lseek(fileinfo.fp_r,0,SEEK_END);//申请一个互斥锁pthread_mutex_init(&fileinfo.mutex,NULL);//创建2个线程pthread_t tid_1,tid_2;if(pthread_create(&tid_1,NULL,callback_1,(void *)&fileinfo) != 0){fprintf(stderr, "pthread_create failed __%d__\n",__LINE__);return -1;}if(pthread_create(&tid_2,NULL,callback_2,(void *)&fileinfo) !=0){fprintf(stderr, "pthread_create failed __%d__\n",__LINE__);return -1;}pthread_join(tid_1,NULL);//阻塞等待线程2完成pthread_join(tid_2,NULL);//阻塞等待线程2完成//销毁互斥锁pthread_mutex_destroy(&fileinfo.mutex);//关闭文件close(fileinfo.fp_r);close(fileinfo.fp_w);printf("主线程准备退出\n");return 0;
}                                                                                             

 

相关文章:

【0803作业】创建两个线程:其中一个线程拷贝图片的前半部分,另一个线程拷贝后半部分(4种方法)

方法一&#xff1a;使用pthread_create、pthread_exit、pthread_join函数【两个线程不共用同一份资源】 先在主函数创建并清空拷贝的目标文件&#xff0c;再创建两个线程&#xff0c;在两个线程内部同时打开要读取的文件以及要拷贝的目标文件&#xff08;两个线程不共用同一份资…...

php运算符的短路特性

php运算符的短路特性 1、逻辑运算符&#xff1a;逻辑与&#xff08;&&)和逻辑或&#xff08;||&#xff09;&#xff0c;存在着短路特性 PHP中有以下两个运算符具有短路的特性&#xff0c;他们是逻辑运算符的逻辑与&#xff08;&&)和逻辑或&#xff08;||&am…...

C语言假期作业 DAY 13

一、选择题 1、如果 x2014 &#xff0c;下面函数的返回值是&#xff08; &#xff09; int fun(unsigned int x) { int n 0; while(x 1) { n; x x | (x 1); } return n; } A: 20 B: 21 C: 23 D 25 答案解析 正确答案&#xff1a;C 这个作用是对整型中0的个数进行统计&…...

以产品经理的角度去讲解原型图---会议OA项目

目录 一.前言 二.原型图 2.1 原型图是什么 3.1 原型图的作用 三.演示讲解 3.1 项目背景 3.2 项目介绍 3.2.1 会议管理&#xff08;会议的发起&#xff0c;通知&#xff09; 3.2.2 投票管理&#xff08;会议的流程重大决策记录&#xff09; 3.2.3 会议室管理 3.2.4 系统管…...

C++ 外部变量和外部函数

1.外部变量 如果一个变量除了在定义它的源文件中可以使用外&#xff0c;还能被其他文件使用&#xff0c;那么就称这个变量为外部变量。命名空间作用域中定义的变量&#xff0c;默认情况下都是外部变量&#xff0c;但在其他文件中如果需要使用这一变量&#xff0c;需要用extern…...

C# Onnx Paddle模型 OCR识别服务

效果 项目 可运行程序exe下载 Demo&#xff08;完整源码&#xff09;下载...

MCUXpresso for VS Code -- 基于VSCode开发RT1176

MCUXpresso for VS Code 是nxp推出插件&#xff0c;旗下MCX LPC, Kinetis和i.MX rt等MCU&#xff0c;都能在VS Code平台进行嵌入式开发。功能框图如下&#xff1a; 前期准备&#xff1a; 软件环境: windows(实际可以跨系统&#xff0c;linux和mac没有测试) VS Code ninja CMa…...

MySQL的使用——【初识MySQL】第二节

MySQL的使用——【初识MySQL】第二节 文章目录 MySQL环境变量的配置&#xff08;如使用Navicat可忽略&#xff09;使用命令行连接MySQL&#xff08;如使用Navicat可忽略&#xff09;步骤注意 NavicatNavicat的下载Navicat的使用连接MySQL新建表 总结总结 MySQL环境变量的配置&a…...

MySQL最终弹-并发(脏读,不可重复读,幻读及区别),JDBC的使用和安装,最全万字

一、&#x1f49b;并发基本概念 并发的基本意思&#xff1a; 什么是并发呢&#xff1f;简单的理解就是同一时间执行 服务器同一时刻&#xff0c;给多个客户端提供服务&#xff5e;&#xff5e;&#xff0c;这两个客户端都可以给服务器提交事务。 如果提交两个事务&#xff0c;改…...

⌈C++⌋从无到有了解并掌握C++面向对象三大特性——封装、继承、多态

前置知识&#xff1a;类和对象 参考书籍&#xff1a;《C Primer 第五版》 目录 什么是面向过程&#xff1f;什么是面向对象&#xff1f; 一、封装 1、封装的含义以及如何实现封装 1.1 访问限定符&#xff08;访问说明符&#xff09; 1.2 什么是封装&#xff1f; 2、封装的优点…...

Element的el-select下拉框多选添加全选功能

先看效果图 全选&#xff1a; 没有选中时&#xff1a; 选中部分&#xff1a; 作者项目使用的是vue3写法&#xff0c;如果是vue2的自己转换一下 html代码&#xff1a; js代码&#xff1a; 拓展 另一种方法&#xff0c;如果不想使用勾选框&#xff0c;可以试试下面的方…...

python调用pytorch的clip模型时报错

使用python调用pytorch中的clip模型时报错&#xff1a;AttributeError: partially initialized module ‘clip’ has no attribute ‘load’ (most likely due to a circular import) 目录 现象解决方案一、查看项目中是否有为clip名的文件二、查看clip是否安装成功 现象 clip…...

MySQL 数据库 binLog 日志的使用

一、概念与作用 binlog&#xff08;二进制日志&#xff09;是MySQL数据库中的一种日志类型。它记录了数据库中的所有更改操作&#xff0c;例如插入、更新、删除操作。binlog以二进制形式存储&#xff0c;因此可以更高效地进行读取和解析。 binlog通常用于以下几个方面&#x…...

Apache Storm入门介绍之三分钟看懂Apache Storm

文章目录 0.前言1. 什么是 Apache Storm&#xff1f;1.1. Nimbus1.2. Zookeeper1.3. Supervisor1.4. Worker1.5 集群模式下各组件职责 2. 核心概念2.1基本架构和任务模型2.2 工作流程 3. 源码地址3.1. 代码结构3.1. 核心模块介绍 4. Storm入门实例0.创建java工程并引入依赖1. 创…...

RF手机天线仿真介绍(三):调谐开关分析

目录 简介调谐开关RON、COFF的影响分析不同位置的调谐器件coff影响分析不同位置的调谐器件Ron影响分析Coff引起谐振的解决示例 调谐开关VPEAK分析调谐开关Vpeak示例 简介 孔径调谐能调节天线的电长度&#xff0c;可将其谐振点切换到所需支持的工作频段。天线孔径调谐器通过改变…...

Ubuntu20.04 + QT5.14.2 + VTK8.2.0 + PCL 1.10 环境配置

目录 Ubuntu20.04 QT5.14.2 VTK8.2.0 PCL 1.10 环境配置一、VTK 编译和安装1、库依赖&#xff1a;2、下载资源&#xff1a;[下载VTK8.2.0](https://www.vtk.org/files/release/8.2/VTK-8.2.0.tar.gz)3、编译&#xff1a;4、安装5、qtcreator 配置编译的libQVTKWidgetPlugin.…...

GPT Prompt编写的艺术:如何提高AI模型的表现力

随着AI技术的迅速发展&#xff0c;人工智能模型变得越来越强大&#xff0c;能够协助我们完成各种任务。然而&#xff0c;如何更好地利用AI的能力仍然存在很大的探索空间。在与AI进行交互的过程中&#xff0c;我们主要依赖于Prompt&#xff0c;不管是直接与大模型交互&#xff0…...

Ubuntu18.04 安装opencv 4.8.0教程(亲测可用)

1. 安装准备 安装前需要下载一些必须的依赖项。 不同版本opencv依赖会有不同&#xff0c;具体见官网opencv安装 sudo apt-get install build-essential sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev sudo apt-…...

【腾讯云Cloud Studio实战训练营】React 快速构建点餐页面

前言&#xff1a; Cloud Studio是一个在线的云集成开发环境&#xff08;IDE&#xff09;&#xff0c;可以让开发人员在浏览器中轻松地开发、测试、调试和部署应用程序。它提供了基于云的计算资源和工具&#xff0c;例如代码编辑器、编译器、调试器、版本控制系统和项目管理工具…...

自监督去噪:Noise2Self原理分析及实现 (Pytorch)

文章地址:https://arxiv.org/abs/1901.11365 代码地址: https://github.com/czbiohub-sf/noise2self 要点   Noise2Self方法不需要信号先验信息、噪声估计信息和干净的训练数据。唯一的假设就是噪声在测量的不同维度上表现出的统计独立性&#xff0c;而真实信号表现出一定的…...

ABB馈线保护 REJ601 BD446NN1XG

配电网基本量程数字继电器 REJ601是一种专用馈线保护继电器&#xff0c;用于保护一次和二次配电网络中的公用事业和工业电力系统。该继电器在一个单元中提供了保护和监控功能的优化组合&#xff0c;具有同类产品中最佳的性能和可用性。 REJ601是一种专用馈线保护继电器&#xf…...

旋量理论:刚体运动的几何描述与机器人应用

旋量理论为描述刚体在三维空间中的运动提供了强大而优雅的数学框架。与传统的欧拉角或方向余弦矩阵相比&#xff0c;旋量理论通过螺旋运动的概念统一了旋转和平移&#xff0c;在机器人学、计算机图形学和多体动力学领域具有显著优势。这种描述不仅几何直观&#xff0c;而且计算…...

年度峰会上,抖音依靠人工智能和搜索功能吸引广告主

上周早些时候举行的第五届年度TikTok World产品峰会上&#xff0c;TikTok推出了一系列旨在增强该应用对广告主吸引力的功能。 新产品列表的首位是TikTok Market Scope&#xff0c;这是一个全新的分析平台&#xff0c;为广告主提供整个考虑漏斗的全面视图&#xff0c;使他们能够…...

C++ 使用 ffmpeg 解码 rtsp 流并获取每帧的YUV数据

一、简介 FFmpeg 是一个‌开源的多媒体处理框架‌&#xff0c;非常适用于处理音视频的录制、转换、流化和播放。 二、代码 示例代码使用工作线程读取rtsp视频流&#xff0c;自动重连&#xff0c;支持手动退出&#xff0c;解码并将二进制文件保存下来。 注意&#xff1a; 代…...

Redis:常用数据结构 单线程模型

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Redis &#x1f525; 常用数据结构 &#x1f433; Redis 当中常用的数据结构如下所示&#xff1a; Redis 在底层实现上述数据结构的过程中&#xff0c;会在源码的角度上对于上述的内容进行特定的…...

Android Camera Hal中通过Neon指令优化数据拷贝

背景描述&#xff1a; Camera apk普通相机模式录像操作时&#xff0c;一般是同时请求两个流&#xff0c;即预览流和录像流。对于两个流输出图像格式和分辨率相同的情况下&#xff0c;是不是可以通过一个流拷贝得到另一个流的数据&#xff0c;进而节省掉一个Sensor输出处理两次…...

JVM内存区域与溢出异常详解

当然可以。以下是结合了程序计数器和Java内存区域以及内存溢出异常的详细解释&#xff1a; JVM内存区域与内存溢出异常 Java虚拟机&#xff08;JVM&#xff09;管理着不同类型的内存区域&#xff0c;每个区域都有其特定的功能和可能导致的内存溢出异常。 程序计数器&#xff…...

MySQL-运维篇

运维篇 日志 错误日志 错误日志是 MySQL 中最重要的日志之一&#xff0c;它记录了当 mysqld 启动和停止时&#xff0c;以及服务器在运行过程中发生任何严重错误时的相关信息当数据库出现任何故障导致无法正常使用时&#xff0c;建议首先查看此日志。 该日志是默认开启的&am…...

【如何做好应用架构?】

一、应用架构定义 应用架构描述了各种用于支持业务架构并对数据架构所定义的各种数据进行出来的应用功能。这些应该功能指的是用来管理在数据架构中定义的数据&#xff0c;并对业务架构中定义的各项业务功能进行支持的能力。 其核心目标是确保应用系统高效、灵活、安全的支撑…...

ngx_stream_geo_module在传输层实现高性能 IP Region 路由

一、模块定位与核心价值 层次&#xff1a;工作在 Stream (TCP/UDP) 层&#xff0c;和 ngx_http_geo_module 的 L7 语义互补。作用&#xff1a;基于客户端 IP 前缀 / 范围生成一个 Nginx 变量&#xff0c;可在后续 proxy_pass、map、limit_conn、access 等指令中使用&#xff0…...