网站界面版式,做跨境电商如何自建站,WordPress如何设置付费下载,免费公章在线生成器方法一#xff1a;使用pthread_create、pthread_exit、pthread_join函数【两个线程不共用同一份资源】 先在主函数创建并清空拷贝的目标文件#xff0c;再创建两个线程#xff0c;在两个线程内部同时打开要读取的文件以及要拷贝的目标文件#xff08;两个线程不共用同一份资…方法一使用pthread_create、pthread_exit、pthread_join函数【两个线程不共用同一份资源】 先在主函数创建并清空拷贝的目标文件再创建两个线程在两个线程内部同时打开要读取的文件以及要拷贝的目标文件两个线程不共用同一份资源。 使用到的函数
标准IO函数fprintf【用于打印错误信息】文件IO函数open、close、lseek有关线程的函数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_ropen(./1.png,O_RDONLY); if(fp_r 0){ERR_MSG(open);}int fp_wopen(./copy.png,O_WRONLY);if(fp_w 0){ERR_MSG(open);}char c 0;off_t lenlseek(fp_r,0,SEEK_END);int i0;lseek(fp_r,0,SEEK_SET);lseek(fp_w,0,SEEK_SET);for(i0;ilen/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_ropen(./1.png,O_RDONLY);if(fp_r 0){ERR_MSG(open);}int fp_wopen(./copy.png,O_WRONLY);if(fp_w 0){ERR_MSG(open);}char c 0;off_t lenlseek(fp_r,0,SEEK_END);int i0;lseek(fp_r,len/2,SEEK_SET);lseek(fp_w,len/2,SEEK_SET);for(i0;ilen/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_wopen(./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达到的效果一致。 使用到的函数
结构体struct标准IO函数fprintf【用于打印错误信息】文件IO函数open、close、lseek有关线程的函数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_rtp-fp_r;int fp_wtp-fp_w;off_t sizetp-size;//将光标偏移到开头拷贝size/2个字节到目标文件中lseek(fp_r,0,SEEK_SET);lseek(fp_w,0,SEEK_SET);char c 0;for(int i0;isize/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_rtp-fp_r;int fp_wtp-fp_w;off_t sizetp-size;//将光标偏移到size/2的位置拷贝size/2个字节到目标文件中lseek(fp_r,size/2,SEEK_SET);lseek(fp_w,size/2,SEEK_SET);char c 0;for(int i0;isize/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_ropen(./1.png,O_RDONLY);if(fileinfo.fp_r 0){ERR_MSG(open);return -1;}//以写的方式打开并创建若存在则清空copy.pngfileinfo.fp_wopen(./copy.png,O_WRONLY|O_CREAT|O_TRUNC,0664);if(fileinfo.fp_w 0){ERR_MSG(open);return -1;}//计算需要拷贝的字节大小fileinfo.sizelseek(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两个线程共享同一份资源利用互斥锁完成任务。 使用到的函数
结构体struct标准IO函数fprintf【用于打印错误信息】文件IO函数open、close、lseek有关线程的函数pthread_create、pthread_exit、pthread_join互斥锁创建互斥锁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.hpthread_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_rfileinfo-fp_r;int fp_wfileinfo-fp_w;off_t sizefileinfo-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 i0;isize/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_rfileinfo-fp_r;int fp_wfileinfo-fp_w;off_t sizefileinfo-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 i0;isize/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_ropen(./1.png,O_RDONLY);if(fileinfo.fp_r 0){ERR_MSG(open);return -1;}//以写的方式打开并创建若存在则清空copy.pngfileinfo.fp_wopen(./copy.png,O_WRONLY|O_CREAT|O_TRUNC,0664);if(fileinfo.fp_w 0){ERR_MSG(open);return -1;}//计算需要拷贝的字节大小fileinfo.sizelseek(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_rfileinfo-fp_r;int fp_wfileinfo-fp_w;off_t sizefileinfo-size;//将光标偏移到开头拷贝size/2个字节到目标文件中lseek(fp_r,0,SEEK_SET);lseek(fp_w,0,SEEK_SET);char c 0;for(int i0;isize/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_rfileinfo-fp_r;int fp_wfileinfo-fp_w;off_t sizefileinfo-size;//将光标偏移到size/2的位置拷贝size/2个字节到目标文件中lseek(fp_r,size/2,SEEK_SET);lseek(fp_w,size/2,SEEK_SET);char c 0;for(int i0;isize/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_ropen(./1.png,O_RDONLY);if(fileinfo.fp_r 0){ERR_MSG(open);return -1;}//以写的方式打开并创建若存在则清空copy.pngfileinfo.fp_wopen(./copy.png,O_WRONLY|O_CREAT|O_TRUNC,0664);if(fileinfo.fp_w 0){ERR_MSG(open);return -1;}//计算需要拷贝的字节大小fileinfo.sizelseek(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两个线程共享同一份资源利用互斥锁完成任务。 使用到的函数
结构体struct标准IO函数fprintf【用于打印错误信息】文件IO函数open、close、lseek有关线程的函数pthread_create、pthread_exit、pthread_join互斥锁创建互斥锁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.hpthread_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_rfileinfo-fp_r;int fp_wfileinfo-fp_w;off_t sizefileinfo-size;char c 0;off_t offset0;for(int i0;isize/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);offsetlseek(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_rfileinfo-fp_r;int fp_wfileinfo-fp_w;off_t sizefileinfo-size;char c 0;off_t offsetsize/2;for(int i0;isize/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);offsetlseek(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_ropen(./1.png,O_RDONLY);if(fileinfo.fp_r 0){ERR_MSG(open);return -1;}//以写的方式打开并创建若存在则清空copy.pngfileinfo.fp_wopen(./copy.png,O_WRONLY|O_CREAT|O_TRUNC,0664);if(fileinfo.fp_w 0){ERR_MSG(open);return -1;}//计算需要拷贝的字节大小fileinfo.sizelseek(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;
}