linux操作系统_实验九-Linux多线程文件传输实现
- 格式:docx
- 大小:93.03 KB
- 文档页数:5
linux 进程与线程通讯实验报告操作系统实验一进程与线程—Linux 进程与线程通讯实验报告操作系统课程设计任务书篇二: 操作系统实验Linux 进程与线程通讯Linux 进程与线程通讯报告人:设计目的1、深刻理解线程和进程的概念2、掌握线程与进程在组成成分上的差别以及与其相适应的通讯方式和应用目标。
设计的内容1、以Linux 系统进程和线程机制为背景,掌握fork() 和clone() 系统调用的2、形式和功能以及与其相适应的高级通讯方式。
由fork 派生的子进程之间通过pipe 通讯,由clone 创建的线程之间通过共享内存通讯,对于后者需要考虑互斥问题。
3、以生产者-消费者问题为例,通过实验理解fork() 和clone() 两个系统调的区别。
程序要求能够创建4 个进程或线程,其中包括两个生产者和两个消费者,生产者和消费者之间能够传递数据。
4、设计准备1、fork 系统调用、pid=fork()创建一个子进程,子进程是父进程的完整复制,正常返回值为非负整数,对于 父进程来说该数大于 0,是子进程的编号 (pid); 对于子进程来说该数为 0。
正是利用反回值的差别可以决定二者不同的后继动作。
2、 clone 系统调用int clone(int (*fn)(void * arg), void *stack, int flags, void * arg);其中 fn 是轻进程所执行的函数, stack 是轻进程所使用的栈, flag 是CLONE_VM, CLONE_FS, CLONE_FILES,LONE_SIGHAND,CLONE_的组合,arg 是调用过程的对应参数。
Clone()的关键是flag 的设定,CLONE_V S 示子进程共享父进程内存,CLONE_F 表示子进程共3、 pipe 系统调用et_val=pipe(fd);参数定义为 int fd[2] 。
创建一个管道文件,返回两个文件描述符 fd[0] 和fd[1] 分别用于管道文件的读和写操作。
Linux下的文件传输由于网络接口MTU的限制(一般mtu为1500),大些的文件只能分多次发送,这样就有几个问题:分几次发送?一次发送多大?保存端的怎么保存?我的办法是:通过定义一个shouldoplen,来说明一次操作需要操作的长度,如果要发送的文件较小(跟buf相比),shouldoplen 就是读取的文件大小,如果文件较大,需要多次发送,那么shouldoplen 就是buf 的长度,通过多次读取,发送,直到发送出去的总长度oplencount 等于文件的大小,这时一个文件就算完整发送成功了。
遇到的问题:传输的文件名(包括路径)不能超过30个字节,否则会报open ***** failed 可以在data.h中设置编译时:gcc socket_server.c -lpthread -o servergcc socket_client.c -o client使用时:在一端打开server#./server令一端使用client#./client ./han/docunt/Linux_dd.pdf Linux_dd.pdf这样就把./han/docunt/Linux_dd.pdf 这就文件发送server端,保存名为Linux_dd.pdf当然,前提是在sock_client.c 中的把目的IP改为你要连接的目的IP。
***********************这是data.h****************#ifndef DATA_H#define DATA_H#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<fcntl.h>#include<signal.h>#include<pthread.h>#include<sys/socket.h>#include<errno.h>#include<arpa/inet.h>#include<netinet/in.h>#include "data.h"typedef unsigned int uint;struct data{char filename[30]; //要发送的文件名(可含路径)char filesavename[30]; //要保存的文件名(可含路径)uint filelen; //文件从字节数uint shouldoplen; //一次要操作的字节数uint oplencount; // 操作的字节总数char filebuf[1300]; //由于mtu为1500,在不改动mtu 的情况下,1300没有问题。
Linux内核多线程实现⽅法 —— kthread_create函数内核经常需要在后台执⾏⼀些操作,这种任务就可以通过内核线程(kernle thread)完成独⽴运⾏在内核空间的标准进程。
内核线程和普通的进程间的区别在于内核线程没有独⽴的地址空间,mm指针被设置为NULL;它只在内核空间运⾏,从来不切换到⽤户空间去;并且和普通进程⼀样,可以被调度,也可以被抢占。
实际上,内核线程只能由其他内核线程创在现有的内核线程中创建⼀个新的内核线程的⽅法:建,在现有的内核线程中创建⼀个新的内核线程的⽅法:kthread_create:创建线程。
struct task_struct *kthread_create(int (*threadfn)(void *data),void *data,const char *namefmt, ...); //注意,第⼆个参数data⽤于向线程传递参数线程创建后,不会马上运⾏,⽽是需要将kthread_create() 返回的task_struct指针传给wake_up_process(),然后通过此函数运⾏线程。
kthread_run :创建并启动线程的函数,相当于kthread_create + wake_up_process功能;struct task_struct *kthread_run(int (*threadfn)(void *data),void *data,const char *namefmt, ...);kthread_stop:通过发送信号给线程,使之退出。
会⼀直运⾏,除⾮该线程主动调⽤do_exit函数,或者其int kthread_stop(struct task_struct *thread); 线程⼀旦启动起来后,会⼀直运⾏他的进程调⽤kthread_stop函数,结束线程的运⾏。
但如果线程函数正在处理⼀个⾮常重要的任务,它不会被中断的。
当然如果线程函数永远不返回并且不检查信号,它将永远都不会停⽌,因此,线程函数必须能让出CPU,以便能运⾏其他线程。
linux下C语言实现文件传输的简单实例实例来自互联网,这段测试代码实现了基本的文件传输原理,没有实现错误处理。
//////////////////////////////////////////////////////////////////////////////////////// file_server.c文件传输顺序服务器示例////////////////////////////////////////////////////////////////////////////////////////本文件是服务器的代码#include <netinet/in.h>// for sockaddr_in#include <sys/types.h>// for socket#include <sys/socket.h>// for socket#include <stdio.h>// for printf#include <stdlib.h>// for exit#include <string.h>// for bzero/*#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>*/#define HELLO_WORLD_SERVER_PORT6666#define LENGTH_OF_LISTEN_QUEUE20#define BUFFER_SIZE 1024#define FILE_NAME_MAX_SIZE 512int main(int argc, char **argv){//设置一个socket地址结构server_addr,代表服务器internet地址, 端口struct sockaddr_in server_addr;bzero(&server_addr,sizeof(server_addr)); //把一段存区的容全部设置为0server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htons(INADDR_ANY);server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);//创建用于internet的流协议(TCP)socket,用server_socket代表服务器socket int server_socket = socket(PF_INET,SOCK_STREAM,0);if( server_socket < 0){printf("Create Socket Failed!");exit(1);}//把socket和socket地址结构联系起来if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))) {printf("Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT);exit(1);}//server_socket用于监听if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) ){printf("Server Listen Failed!");exit(1);}while (1) //服务器端要一直运行{//定义客户端的socket地址结构client_addrstruct sockaddr_in client_addr;socklen_t length = sizeof(client_addr);//接受一个到server_socket代表的socket的一个连接//如果没有连接请求,就等待到有连接请求--这是accept函数的特性//accept函数返回一个新的socket,这个socket(new_server_socket)用于同连接到的客户的通信//new_server_socket代表了服务器和客户端之间的一个通信通道//accept函数把连接到的客户端信息填写到客户端的socket地址结构client_addr中int new_server_socket = accept(server_socket,(struct sockaddr*)&client_addr,&length);if ( new_server_socket < 0){printf("Server Accept Failed!\n");break;}char buffer[BUFFER_SIZE];bzero(buffer, BUFFER_SIZE);length = recv(new_server_socket,buffer,BUFFER_SIZE,0);//这里先接收客户端发来的要获取的文件名if (length < 0){printf("Server Recieve Data Failed!\n");break;}char file_name[FILE_NAME_MAX_SIZE+1];bzero(file_name, FILE_NAME_MAX_SIZE+1);strncpy(file_name, buffer,strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));//int fp = open(file_name, O_RDONLY);//if( fp < 0 )FILE * fp = fopen(file_name,"r");if(NULL == fp ){printf("File:\t%s Not Found\n", file_name);}else{bzero(buffer, BUFFER_SIZE);int file_block_length = 0;//while( (file_block_length = read(fp,buffer,BUFFER_SIZE))>0)while( (file_block_length = fread(buffer,sizeof(char),BUFFER_SIZE,fp))>0){printf("file_block_length = %d\n",file_block_length);//发送buffer中的字符串到new_server_socket,实际是给客户端if(send(new_server_socket,buffer,file_block_length,0)<0){printf("Send File:\t%s Failed\n", file_name);break;}bzero(buffer, BUFFER_SIZE);}//这段代码是循环读取文件的一段数据,在循环调用send,发送到客户端,这里强调一点的TCP每次接受最多是1024字节,多了就会分片,因此每次发送时尽量不要超过1024字节。
Linux多线程编程并传递多个参数实例Linux多线程编程并传递多个参数实例0. 怎么理解 void* (*start_routine)(void *)? 你定义了⼀个函数指针。
名字叫 start_routine 。
这个函数的返回值是void *(⼀个指针)参数是void *(⼀个指针)⼀般这种写法最好⽤typedef void* (start_routine)(void ) ,然后⽤start_routine当作⼀种类型来使⽤。
如: start_routine pfoo;调⽤的时候: *pfoo(p);例⼦详细解析:⼀. pthread_create()与pthread_join()函数#include <pthread.h> int pthread_join(pthread_t thread, void **retval);1. pthread_join函数作⽤ pthread_join函数作⽤是在⼀个线程中以阻塞的⽅式等待另⼀个线程(线程标识符为thread)的退出。
如果等待的进程已经结束,那么该函数会⽴即返回。
retval是⽤户定义的指针,⽤来存储被等待线程的返回值。
返回值: 0 -- 成功,失败 -- 错误号errno2. pthread_join的应⽤使⼀个线程等待另⼀个线程的结束代码中如果没有pthread_join主线程会很快结束,从⽽从⽽合整个进程线束,从⽽使创建的线程没有机会执⾏就结束了,在主线程加⼊pthread_join后,主线程会阻塞等待直到(被等待的)线程结束后,主线程⾃⼰才结束,从⽽使创建的线程有机会执⾏。
3. ⼀个线程不能被多个线程等待,否则第⼀个接收到信号的线程成功返回,其余调⽤ pthread_join 的线程则返回错误代码ESRCH。
#include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);1. pthread_create函数的作⽤ 创建⼀个线程,成功时返回0,错误时返回errno。
Linux命令行多线程、断点续传下载工具运维工作中常会在linux命令行下载外网文件或内网进行大文件传输,经常使用的文本下载工具wget、curl,今天给大家推荐支持Linux命令行多线程、断点续传下载工具axel和myget。
1、系统环境# lsb_release -aLSBVersion: :core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-a md64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd64:printin g-4.0-ia32:printing-4.0-noarchDistributor ID: CentOSDescription: CentOS release 5.8 (Final)Release: 5.8Codename: Final2、下载工具安装、使用方法介绍2.1 wgetCentOS 默认已经安装,如需安装请运行# yum install wget -ywget版本信息# wget -VGNU Wget 1.11.4 Red Hat modified此工具比较常用,使用方法、参数略2.2 Axel 下载安装安装axel# rpm -ivh axel-2.4-1.el5.rf.x86_64.rpmaxel版本# axel -VAxel version 2.4 (Linux)axel命令使用方法:axel [选项参数] url1 [url2] [url……]axel 参数:--max-speed=x #限速值最高速度-s xSpecify maximum speed (bytes per second)--num-connections=x-n x #连接数Specify maximum number of connections--output=f #下载为本地文件-o fSpecify local output file--search[=x] #搜索镜像-S [x]Search for mirrors and download from x servers--header=x-H x #添加头文件字符串Add header string--user-agent=x #设置UA-U xSet user agent--no-proxy #不使用代理服务器-NJust don't use any proxy server --quiet--quiet, -qNo output to stdout. #静默模式,不输出到标准输出--verbose-vMore status information #更多状态信息--alternate--help #帮助-h--version #版本-V2.3 myget 下载、安装[root@cobbler-1014 ~]# wget/release/myget-0.1.2.tar.gz [root@cobbler-1014 ~]# tar zxf myget-0.1.2.tar.gz [root@cobbler-1014 ~]# cd myget-0.1.2# ./configure && make && make installmytget版本,注意myget命令为mytget命令mytget用法mytget [选项] [url]参数-b, --debug Show the debug message #看调试信息-c, --count=num Set the retry count to [num], no limit when "0", the default is "99" #设置重试次数,0为无限,默认是99次。
Linux命令行中的文件同步和数据迁移技巧在Linux命令行中,文件同步和数据迁移是一项非常常见且重要的操作。
无论是跨服务器迁移数据还是在本地进行文件同步,掌握一些文件同步和数据迁移技巧可以帮助高效完成任务。
本文将介绍一些常用的Linux命令和工具,帮助您掌握文件同步和数据迁移的技巧。
1. 常用的文件同步命令1.1. rsync命令rsync是一种功能强大的文件同步和备份工具,可以在本地或网络上同步文件和目录。
其基本的命令格式如下:```shellrsync [option] source destination```其中,source表示源文件或源目录,destination表示目标文件或目标目录。
rsync命令的一些常用选项包括:- `-a`:归档模式,同步并保持文件属性、权限等信息。
- `-v`:显示详细输出。
- `-z`:启用压缩传输,减少数据传输量。
- `-r`:递归同步子目录。
- `-u`:仅同步更新的文件。
例如,将本地目录/tmp/myfiles同步到远程服务器的/home/user目录下,可以使用以下命令:```shellrsync -avz /tmp/myfiles user@remote:/home/user```1.2. scp命令scp是secure copy的缩写,是一个在本地和远程系统之间进行文件拷贝的命令行工具。
其基本的命令格式如下:```shellscp [option] source destination```其中,source表示源文件或源目录,destination表示目标文件或目标目录。
scp命令的一些常用选项包括:- `-r`:递归拷贝目录。
- `-P`:指定端口号。
- `-i`:指定密钥文件。
- `-v`:显示详细输出。
例如,将本地目录/tmp/myfiles拷贝到远程服务器的/home/user目录下,可以使用以下命令:```shellscp -r /tmp/myfiles user@remote:/home/user```2. 实现文件同步的工具2.1. lsyncdlsyncd是一种基于rsync的实时文件同步工具,能够实时监测文件变化并同步更新到指定目录。
两台linux主机传送大文件的方法-概述说明以及解释1.引言1.1 概述概述:在进行文件传输时,Linux主机之间有多种方法可供选择。
本文将介绍三种常用的方法:使用SCP命令进行文件传输、使用rsync命令进行文件传输,以及使用FTP服务器进行文件传输。
这些方法各有优缺点,我们将对它们进行详细的比较和总结。
同时,我们也会给出我们的最佳推荐方法,并展望未来的发展方向。
文件传输在日常工作和生活中非常常见,特别是在Linux环境下。
无论是在服务器之间进行文件备份、数据同步,还是在不同的开发环境中共享文件,选择合适的文件传输方法能够提高效率、节省时间。
在接下来的章节中,我们将详细介绍每种方法的基本用法和高级用法,并分析它们的优缺点。
首先,我们将介绍SCP命令,它是一种简单直观的文件传输方式。
然后,我们将介绍rsync命令,它提供了更为灵活和高效的文件传输选项。
最后,我们将介绍FTP服务器的搭建和使用方法,探讨它的优势和不足。
通过对这些方法的比较和分析,我们将总结出每种方法的适用场景,并给出我们的最佳推荐方法。
此外,我们也会对未来的文件传输技术发展进行展望,以期提升文件传输的速度、安全性和便利性。
通过本文的阅读,读者将能够了解到不同的文件传输方法之间的差异,为自己的工作环境选择合适的传输方式提供参考和指导。
接下来,让我们开始介绍第一种传输方法:使用SCP命令进行文件传输。
1.2文章结构文章结构部分内容如下:2. 正文2.1 方法一:使用SCP命令进行文件传输2.1.1 SCP命令的基本用法2.1.2 SCP命令的高级用法2.1.3 SCP命令的优缺点2.2 方法二:使用rsync命令进行文件传输2.2.1 rsync命令的基本用法2.2.2 rsync命令的高级用法2.2.3 rsync命令的优缺点2.3 方法三:使用FTP服务器进行文件传输2.3.1 搭建FTP服务器2.3.2 使用FTP客户端进行文件传输2.3.3 FTP服务器的优缺点3. 结论3.1 对比和总结各种方法的优缺点3.2 推荐最佳的方法3.3 展望未来的发展方向在本文中,我们将重点探讨两台Linux主机之间传送大文件的方法。
Linux并发编程实验多线程、多进程编程一.实验目的和要求二、实验内容三、实验结果与分析1、进程实验(1)分别创立4个C文件,get.c、copy.c、put.c以及main.c分别实验读入,拷贝,输出,及前三个函数的调用;(2)定义三个缓冲区,其中一个记录对各项操作的选择,另外两个用来传输拷贝文件内容,相当于图中的缓冲区s和缓冲区t;(3)并发执行时定义了4个信号灯,分别用来控制缓冲区s是否有内容,缓冲区s是否空,缓冲区t是否有内容,缓冲区t是否为空;顺序执行时定义了三个信号灯,让get、copy、put分别其按顺序依次执行。
(4)创建三个进程分别实现get、copy、put功能;(5)并发时原理如下If(f不为空){get(s,f);while(誊抄未完成){t=s;cobeginput(t,g);get(s,f);coend;}}(6)顺序执行时原理如下:while(f不为空){input;output;}(7)创建一个字符文档如下,大小为42.4KB,内容为一连串的字符此时文件比较小用并发和顺序所得执行结果如下由此可知当文件很小时,并发执行和顺序执行比本感觉不出差距。
(8)创建一个一个较大的f.txt文档,大小为113.5KB,内容为一连串字符,如下:此时文件较大,并发执行和顺序执行的程序运行结果如下所示:此时才能看出两者之间有细小的差别,顺序执行效率小于并发执行的效率!但还是可见差距非常不明显!(9)分析:对于进程而言,顺序执行和并发执行之间的差距并不是那么明显,尤其是在拷贝文件较小时,基本感觉不出差距,只有在拷贝文件很大时才能有感觉到明显的差距。
2、线程实验(1)实验原理与进程一致,只是这次用的是一个thread。
C文件,内部有4个函数分别为get、copy、put、main来实现全部功能。
并且创建的为3个线程。
(2)创建一个f.txt文件,大小为113.5KB,内容为一串连续字符,如下所示并发和顺序的执行结果如下所示:并发执行的结果为4.83秒,而顺序执行在两分钟后还是没有完成,用ctrl+C打断,可见当要拷贝的文件很大时,线程的并发和顺序执行之间的差距是非常明显的!(3)创建一个较小的f.txt文件,大小为7.6KB,内容为一连串的字符,如下所示:此时的运行结果如下所示:可见,当拷贝的文件较小时,线程的顺序与并发执行指尖的差距也会变小。