【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.png
	fileinfo.fp_r=open("./1.png",O_RDONLY);
	if(fileinfo.fp_r < 0)
	{
		ERR_MSG("open");
		return -1;
	}
	//以写的方式打开并创建(若存在则清空)copy.png
	fileinfo.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.png
	fileinfo.fp_r=open("./1.png",O_RDONLY);
	if(fileinfo.fp_r < 0)
	{
		ERR_MSG("open");
		return -1;
	}
	//以写的方式打开并创建(若存在则清空)copy.png
	fileinfo.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);  //分离线程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);//阻塞等待线程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.png
	fileinfo.fp_r=open("./1.png",O_RDONLY);
	if(fileinfo.fp_r < 0)
	{
		ERR_MSG("open");
		return -1;
	}
	//以写的方式打开并创建(若存在则清空)copy.png
	fileinfo.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);  //分离线程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");
	//销毁互斥锁
	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.png
    fileinfo.fp_r=open("./1.png",O_RDONLY);
    if(fileinfo.fp_r < 0)
    {
        ERR_MSG("open");
        return -1;
    }
    //以写的方式打开并创建(若存在则清空)copy.png
    fileinfo.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;
}                                                                                             
                                                                                                         

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/58262.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vulnhub: BlueMoon: 2021靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.174 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.174 80端口目录爆破&#xff0c;发现文件&#xff1a;hidden_text gobuster dir -u http://192.168.111.174 -w /usr/sha…

牛客网Verilog刷题——VL41

牛客网Verilog刷题——VL41 题目答案 题目 请设计一个可以实现任意小数分频的时钟分频器&#xff0c;比如说8.7分频的时钟信号&#xff0c;注意rst为低电平复位。提示&#xff1a;其实本质上是一个简单的数学问题&#xff0c;即如何使用最小公倍数得到时钟周期的分别频比。设小…

RabbitMQ教程与安装

1 在CentOS7中安装RabbitMQ 在 CentOS 中安装 RabbitMQ 的命令如下&#xff1a; 首先&#xff0c;确保已经安装了 EPEL 软件包存储库。如果没有&#xff0c;请运行以下命令安装它&#xff1a; sudo yum install epel-release 更新系统的软件包列表&#xff1a; sudo yum upda…

成本控制策略:加强企业安全

我们生活在一个不确定的时代。大多数经济学家预测&#xff0c;今年全球经济将继续放缓&#xff0c;亚太地区当然也不会逆势而上。 在供应链问题、大规模裁员、高通胀和高利率之间&#xff0c;我们毫不奇怪地看到大多数公司和行业采取谨慎态度&#xff0c;战略、增长计划和预算…

艺术二维码 API 申请及使用

艺术二维码是一种创新的技术产品&#xff0c;它将二维码与美观的背景图像相结合&#xff0c;创造出既实用又美观的作品。它们不仅具有传统二维码的功能性&#xff0c;能被智能设备快速扫描识别&#xff0c;还加入了艺术元素&#xff0c;增强了视觉吸引力和品牌识别度。其中&…

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

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

opencv-34 图像平滑处理-2D 卷积 cv2.filter2D()

2D卷积是一种图像处理和计算机视觉中常用的操作&#xff0c;用于在图像上应用滤波器或卷积核&#xff0c;从而对图像进行特征提取、平滑处理或边缘检测等操作。 在2D卷积中&#xff0c;图像和卷积核都是二维的矩阵或数组。卷积操作将卷积核在图像上滑动&#xff0c;对每个局部区…

Robot Framweork之UI自动化测试---分层设计

Robot Framework 的分层思想是一种测试设计和代码组织的模式&#xff0c;它将测试用例的实现和测试执行逻辑分离&#xff0c;以提高测试的可维护性、可读性和可扩展性。 一、分层思想 在实际项目中&#xff0c;一般分为三层&#xff1a;元素层&#xff0c;流程层&#xff0c;用…

k8s之Helm安装

一、最快安装–官网提供的脚本–默认获取最新版本 cd /usr/local/src/ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.shhelm search hub wordpresssource <(helm completion bash) h…

pycharm——漏斗图

import pyecharts.options as opts from pyecharts.charts import Funnel""" Gallery 使用 pyecharts 1.1.0 参考地址: https://echarts.apache.org/examples/editor.html?cfunnel目前无法实现的功能:1、暂时无法对漏斗图的长宽等范围操作进行修改 ""…

Metric3D:Towards Zero-shot Metric 3D Prediction from A Single Image

参考代码&#xff1a;Metric3D 介绍 在如MiDas、LeReS这些文章中对于来源不同的深度数据集使用归一化深度作为学习目标&#xff0c;则在网络学习的过程中就天然失去了对真实深度和物体尺寸的度量能力。而这篇文章比较明确地指出了影响深度估计尺度变化大的因素就是焦距 f f f…

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.…

解密Redis:应对面试中的缓存相关问题2

面试官&#xff1a;Redis集群有哪些方案&#xff0c;知道嘛&#xff1f; 候选人&#xff1a;嗯~~&#xff0c;在Redis中提供的集群方案总共有三种&#xff1a;主从复制、哨兵模式、Redis分片集群。 面试官&#xff1a;那你来介绍一下主从同步。 候选人&#xff1a;嗯&#xff…

C++ 左值和右值

C 左值和右值 左值、右值左值引用、右值引用std::move()std::move()的实现引用折叠 完美转发forward()的实现函数返回值是左值还是右值如何判断一个值是左值还是右值 左值、右值 在C11中所有的值必属于左值、右值两者之一&#xff0c;右值又可以细分为纯右值、将亡值。在C11中…

git clone 登录 github

git clone 登录 github 目录概述需求&#xff1a; 设计思路实现思路分析1.github 设置setting2.输入passwd 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result…

JVM基础篇-本地方法栈与堆

JVM基础篇-本地方法栈与堆 本地方法栈 什么是本地方法? 本地方法即那些不是由java层面实现的方法&#xff0c;而是由c/c实现交给java层面进行调用&#xff0c;这些方法在java中使用native关键字标识 public native int hashCode()本地方法栈的作用? 为本地方法提供内存空…

VR虚拟仿真技术在道路桥梁中有哪些具体应用?

虚拟现实(VR)是一种新兴的技术&#xff0c;可以为桥梁工程提供许多应用场景。以下是一些可能的应用场景&#xff1a; 1.桥梁设计和模拟 VR元宇宙可以用于桥梁的设计和模拟。工程师可以使用VR技术来创建桥梁的三维模型&#xff0c;并对其进行测试和优化。这可以帮助工程师更好地…

深入理解TCP三次握手:连接可靠性与安全风险

目录 导言TCP简介和工作原理的回顾TCP三次握手的目的和步骤TCP三次握手过程中可能出现的问题和安全风险为什么TCP三次握手是必要的&#xff1f;是否可以增加或减少三次握手的次数&#xff1f;TCP四次挥手与三次握手的异同点 导言 在网络通信中&#xff0c;TCP&#xff08;Tra…

spring — Spring Security 5.7与6.0差异性对比

1. spring security Spring Security 是一个提供身份验证、授权和针对常见攻击保护的框架。 凭借对保护命令式和反应式应用程序的一流支持&#xff0c;它成为基于Spring的标准安全框架。 Spring Security 在最近几个版本中配置的写法都有一些变化&#xff0c;很多常见的方法都…

【NLP-新工具】语音转文本与OpenAI的用途

一、说明 OpenAI最近2022发布了一个名为Whisper的新语音识别模型。与DALLE-2和GPT-3不同&#xff0c;Whisper是一个免费的开源模型。它的主要功能就是将语音翻译成文本。本文将介绍如何使用这个重要应用库。 二、 Whisper概念 2.1 Whisper是啥&#xff1f; Whisper 是一种自动…