Linux 系统开发5 进程间通信 pipe() fifo() mmap()

pipe()管道通信介绍

pipe()父子进程通信案例

pipe()使用管道有一些限制

pipe()管道缓存区大小

pipe() 读端非阻塞管道

fifo()管道文件

fifo()写端/读端程序

管道文件在磁盘上的大小是0

mmap()将文件映射到内存

mmap()写端/读端程序

mmap()传输结构体数据,删除临时文件

pipe()管道通信

管道作用于有学员关系的进程之间,通过fork()来传递

管道在kernel空间,先pipe在fork,进程继承

管道是一种最基本的IPC机制,由pipe函数创建:

#include

int pipe(int filedes[2]);

管道作用于有血缘关系的进程之间,通过fork来传递

调用pipe函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读端一个

写端,然后通过filedes参数传出给用户程序两个文件描述符,filedes[0]指向管道的读

端,filedes[1]指向管道的写端(很好记,就像0是标准输入1是标准输出一样)。所以管道

在用户程序看起来就像一个打开的文件,通过read(filedes[0]);或者write(filedes[1]);

向这个文件读写数据其实是在读写内核缓冲区。pipe函数调用成功返回0,调用失败返

回-1。

开辟了管道之后如何实现两个进程间的通信呢?比如可以按下面的步骤通信。

看图

1.父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端。

2.父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。

3.父进程关闭管道读端,子进程关闭管道写端。父进程可以往管道里写,子进程可以从

管道里读,管道是用环形队列实现的,数据从写端流入从读端流出,这样就实现了进程间通

信。

例 pipe管道chunli@ubuntu:~/linux_c$ cat main.c

#include

#include

#include

#include

#include

#include

#include

int main(int num,char **args,char **env)

{

int fd[2] = {0};

char buf[1024] = "Hello World!  ";

pid_t pid = 0;

if(pipe(fd) == -1)

{

perror("pipe");

exit(1);

}

pid = fork();

//父写子读

if(pid >0)//在父进程,关闭父读

{

close(fd[0]);

sleep(1);//等n秒 再给子进程发数据

write(fd[1],buf,strlen(buf));

wait(NULL);

}

else if(pid == 0)//在子进程,关闭子写

{

char buf[1024] = {0};

int len = 0;

close(fd[1]);//关闭写端

len = read(fd[0],buf,sizeof(buf));

sprintf(buf,"%s\n",buf);

write(STDOUT_FILENO,buf,strlen(buf));

}

return 0;

}

chunli@ubuntu:~/linux_c$ gcc -o app main.c  && ./app

Hello World!

chunli@ubuntu:~/linux_c$

使用管道有一些限制:

两个进程通过一个管道只能实现单向通信,比如上面的例子,父进程写子进程读,如果

有时候也需要子进程写父进程读,就必须另开一个管道。请读者思考,如果只开一个管道,

但是父进程不关闭读端,子进程也不关闭写端,双方都有读端和写端,为什么不能实现双向

通信?

管道的读写端通过打开的文件描述符来传递,因此要通信的两个进程必须从它们的公共

祖先那里继承管道文件描述符。上面的例子是父进程把文件描述符传给子进程之后父子进程

之间通信,也可以父进程fork两次,把文件描述符传给两个子进程,然后两个子进程之间通

信,总之需要通过fork传递文件描述符使两个进程都能访问同一管道,它们才能通信。

使用管道需要注意以下4种特殊情况(假设都是阻塞I/O操作,没有设置O_NONBLOCK标

志):

1.如果所有指向管道写端的文件描述符都关闭了(管道写端的引用计数等于0),而仍

然有进程从管道的读端读数据,那么管道中剩余的数据都被读取后,再次read会返回0,就

像读到文件末尾一样。

2.如果有指向管道写端的文件描述符没关闭(管道写端的引用计数大于0),而持有管

道写端的进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数

据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回。

3.如果所有指向管道读端的文件描述符都关闭了(管道读端的引用计数等于0),这时

有进程向管道的写端write,那么该进程会收到信号SIGPIPE,通常会导致进程异常终止。讲

信号时会讲到怎样使SIGPIPE信号不终止进程。

4.如果有指向管道读端的文件描述符没关闭(管道读端的引用计数大于0),而持有管

道读端的进程也没有从管道中读数据,这时有进程向管道写端写数据,那么在管道被写满时

再次write会阻塞,直到管道中有空位置了才写入数据并返回。

管道的这四种特殊情况具有普遍意义。

非阻塞管道, fcntl函数设置O_NONBLOCK标志

fpathconf(int fd, int name)测试管道缓冲区大小,_PC_PIPE_BUF

测试管道缓存区大小chunli@ubuntu:~/linux_c$ cat main.c

#include

#include

#include

#include

#include

#include

#include

int main(int num,char **args,char **env)

{

int fd[2] = {0};

pipe(fd);

printf("%ld \n",fpathconf(fd[0],_PC_PIPE_BUF));

return 0;

}

chunli@ubuntu:~/linux_c$ gcc main.c  && ./a.out

4096

chunli@ubuntu:~/linux_c$

pipe() 读端非阻塞管道chunli@ubuntu:~/linux_c$ cat main.c

#include

#include

#include

#include

#include

#include

#include

#include

void err(char *p,int exitno)

{

perror(p);

exit(exitno);

}

int main(void)

{

int fd[2];//fd[0] 读端,fd[1]  写端

char str[1024] = "Hello Linux!\n";

if(pipe(fd) == -1)//如果创建管道出错

{

err("pipe",1);

}

//创建子进程

pid_t pid = fork();

if(pid > 0)//大于0就是父进程

{

close(fd[0]);//关闭读端

sleep(5);

write(fd[1],str,strlen(str));//向管道写入数据

close(fd[1]);//关闭写端

wait(NULL);//给子进程收尸

}

else if(pid == 0)//等于就是子进程

{

int len = 0;

int flags = 0;

char buf[1024] = {"\0"};

close(fd[1]);//关闭写端

//设置为非阻塞

flags = fcntl(fd[0],F_GETFL);

flags |= O_NONBLOCK;

fcntl(fd[0],F_SETFL,flags);

tryagain:

len = read(fd[0],buf,sizeof(buf));

if(len == -1)

{

if(errno == EAGAIN)

{

write(STDOUT_FILENO,"再试一次\n",13);

sleep(1);

goto tryagain;

}

else

{

err("read",3);

}

}

else

{

write(STDOUT_FILENO,buf,len);

close(fd[0]);

}

}

else

{

err("fork",2);

}

return 0;

}

chunli@ubuntu:~/linux_c$ gcc main.c  -o app && ./app

再试一次

再试一次

再试一次

再试一次

再试一次

Hello Linux!

chunli@ubuntu:~/linux_c$

fifo()管道文件

没有实际的大小,这是一条通往内核缓存区的通道

fifo有名管道

chunli@ubuntu:~/linux_c/fifo$ mkfifo myfifo

chunli@ubuntu:~/linux_c/fifo$ ll myfifo

prw-rw-r-- 1 chunli chunli 0 8月  10 15:09 myfifo|

chunli@ubuntu:~/linux_c/fifo$ stat myfifo

文件:'myfifo'

大小:0               块:0          IO 块:4096   先进先出

设备:801h/2049d        Inode:398096      硬链接:1

权限:(0664/prw-rw-r--)  Uid:( 1000/  chunli)   Gid:( 1000/  chunli)

最近访问:2016-08-10 15:09:31.925839651 +0800

最近更改:2016-08-10 15:09:31.925839651 +0800

最近改动:2016-08-10 15:09:31.925839651 +0800

创建时间:-

chunli@ubuntu:~/linux_c/fifo$ file myfifo

myfifo: fifo (named pipe)

chunli@ubuntu:~/linux_c/fifo$

fifo()写端/读端程序我的文件:

chunli@ubuntu:~/linux_c/fifo$ ll

总用量 36K

-rw-rw-r-- 1 chunli chunli  623 8月  10 16:25 fifo_1.c

-rw-rw-r-- 1 chunli chunli  566 8月  10 16:21 fifo_2.c

prw-rw-r-- 1 chunli chunli    0 8月  10 16:25 myfifo|

-rwxrwxr-x 1 chunli chunli  13K 8月  10 16:25 read*

-rwxrwxr-x 1 chunli chunli 8.8K 8月  10 16:25 write*

chunli@ubuntu:~/linux_c/fifo$

fifo写端:

chunli@ubuntu:~/linux_c/fifo$ cat fifo_1.c

#include

#include

#include

#include

#include

#include

#include

void sys_err(char *p,int exitno)

{

perror(p);

exit(exitno);

}

//fifo 管道写端

int main(int argc,char *argv[])

{

if(argc

{

printf("need more parameter\n");

exit(1);

}

int fd = open(argv[1],O_WRONLY);

//printf("debug\n");

if(fd == -1)

{

sys_err("open",2);

}

char buf[1024] = "Hello Linux\n";

int len = write(fd,buf,strlen(buf));

if(len == -1)

{

sys_err("write",3);

}

else

{

write(STDOUT_FILENO,"写入成功\n",13);

}

close(fd);

return 0;

}

chunli@ubuntu:~/linux_c/fifo$ gcc fifo_1.c -o write && ./write myfifo

写入成功

chunli@ubuntu:~/linux_c/fifo$

fido读端程序:

chunli@ubuntu:~/linux_c/fifo$ cat fifo_2.c

#include

#include

#include

#include

#include

#include

#include

void sys_err(char *p,int exitno)

{

perror(p);

exit(2);

}

//fifo 管道写端

int main(int argc,char *argv[])

{

if(argc

{

printf("need more parameter\n");

exit(1);

}

int fd = open(argv[1],O_RDONLY);

if(fd == -1)

{

sys_err("open",2);

}

char buf[1024] = {"\0"};

int len = read(fd,buf,sizeof(buf));

if(len == -1)

{

sys_err("write",3);

}

write(STDOUT_FILENO,buf,len);

close(fd);

return 0;

}

chunli@ubuntu:~/linux_c/fifo$ gcc -o read fifo_2.c  && ./read  myfifo

Hello Linux

chunli@ubuntu:~/linux_c/fifo$

管道文件在磁盘上的大小是0chunli@ubuntu:~/linux_c/fifo$ stat myfifo

文件:'myfifo'

大小:0         块:0          IO 块:4096   先进先出

设备:801h/2049dInode:398096      硬链接:1

权限:(0664/prw-rw-r--)  Uid:( 1000/  chunli)   Gid:( 1000/  chunli)

最近访问:2016-08-10 16:30:07.533706359 +0800

最近更改:2016-08-10 16:30:07.533706359 +0800

最近改动:2016-08-10 16:30:07.533706359 +0800

创建时间:-

chunli@ubuntu:~/linux_c/fifo$

mmap()将文件映射到内存,为文件进行读写

chunli@ubuntu:~/linux_c/mmap$ echo "hello Linux!" > hello

chunli@ubuntu:~/linux_c/mmap$ od -tx1 -tc hello

0000000  68  65  6c  6c  6f  20  4c  69  6e  75  78  21  0a

h   e   l   l   o       L   i   n   u   x   !  \n

0000015

chunli@ubuntu:~/linux_c/mmap$

chunli@ubuntu:~/linux_c/mmap$ cat main.c

#include

#include

#include

#include

#include

#include

#include

#include

void sys_err(char *p,int exitno)

{

perror(p);

exit(exitno);

}

int main(int argc,char **argv)

{

if(argc

{

printf("参数不够\n");

exit(1);

}

int fd = open(argv[1],O_RDWR);

if(fd == -1)

{

sys_err("open",1);

}

int len = lseek(fd,0,SEEK_END);

if(len == -1)

{

sys_err("lseek",2);

}

//自动分配地址空间,申请len的字节,读写模式,fd文件,0偏移

char *p = mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

if(p == MAP_FAILED)

{

sys_err("mmap",3);

}

close(fd);//关闭关联的文件,内存映射依然可对其读写

//修改文件的值

int i = 0;

for(i = 0;i

{

*p++  = 0x30 + i;

}

*--p = '\n';//最后一个改为换行

munmap(p,len);//避免内存泄漏

return 0;

}

chunli@ubuntu:~/linux_c/mmap$ gcc -o app main.c  && ./app hello && cat hello

0123456789:;

chunli@ubuntu:~/linux_c/mmap$ cat hello

mmap()内存共享映射,写端/读端程序写端:

chunli@ubuntu:~/linux_c/mmap$ cat write.c

#include

#include

#include

#include

#include

#include

#include

#include

#define SIZE 128//缓冲区128字节

void sys_err(char *p,int exitno)

{

perror(p);

exit(exitno);

}

int main(int argc,char **argv)

{

if(argc

{

printf("参数不够\n");

exit(1);

}

//创建文件

int fd = open(argv[1],O_RDWR | O_CREAT ,0777);

if(fd == -1)

{

sys_err("open",1);

}

lseek(fd,SIZE -1 ,SEEK_SET);

write(fd,"\0",1);

//自动分配地址空间,申请len的字节,读写模式,fd文件,0偏移

char *p = mmap(NULL,SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

if(p == MAP_FAILED)//检查映射是否成功

{

sys_err("mmap",3);

}

close(fd);//关闭关联的文件,内存映射依然可对其读写

//修改文件的值

int i = 0;

for(i = 0;i

{

p[i]  = 0x61 + i%26;

}

p[SIZE-1] = '\n';

munmap(p,SIZE);//避免内存泄漏

return 0;

}

chunli@ubuntu:~/linux_c/mmap$ gcc -o write write.c  && ./write hello && cat hello

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

chunli@ubuntu:~/linux_c/mmap$

读端:

chunli@ubuntu:~/linux_c/mmap$ cat read.c

#include

#include

#include

#include

#include

#include

#include

#include

void sys_err(char *p,int exitno)

{

perror(p);

exit(exitno);

}

int main(int argc,char **argv)

{

if(argc

{

printf("参数不够\n");

exit(1);

}

//创建文件

int fd = open(argv[1],O_RDWR);

if(fd == -1)

{

sys_err("open",1);

}

int len = lseek(fd,0,SEEK_END);

if(len == -1)

{

sys_err("lseek",2);

}

//自动分配地址空间,申请len的字节,读写模式,fd文件,0偏移

char *p = mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

if(p == MAP_FAILED)//检查映射是否成功

{

sys_err("mmap",3);

}

close(fd);//关闭关联的文件,内存映射依然可对其读写

char buf[4096] = {"\0"};

int i = 10;

while(i--)

{

printf("%s",p);

sleep(1);

}

munmap(p,len);//避免内存泄漏

return 0;

}

chunli@ubuntu:~/linux_c/mmap$ gcc -o read read.c && ./read hello

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw

chunli@ubuntu:~/linux_c/mmap$

文件已经映射到内核缓冲,速度并不是硬盘IO那么慢

mmap()传输结构体数据,删除临时文件读端:

chunli@ubuntu:~/linux_ccat read.c

#include

#include

#include

#include

#include

#include

#include

#include

void sys_err(char *p,int exitno)

{

perror(p);

exit(exitno);

}

struct Stu

{

int id;

char name[20];

char sex;

};

int main(int argc,char **argv)

{

if(argc

{

printf("参数不够\n");

exit(1);

}

//创建文件

int fd = open(argv[1],O_RDWR);

if(fd == -1)

{

sys_err("open",1);

}

int len = lseek(fd,0,SEEK_END);

if(len == -1)

{

sys_err("lseek",2);

}

//自动分配地址空间,申请len的字节,读写模式,fd文件,0偏移

struct Stu  *p = mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

if(p == MAP_FAILED)//检查映射是否成功

{

sys_err("mmap",3);

}

close(fd);//关闭关联的文件,内存映射依然可对其读写

int i = 10;

while(i--)

{

printf("%d  %s  %c \n",p->id,p->name,p->sex);

sleep(1);

}

munmap(p,len);//避免内存泄漏

return 0;

}

chunli@ubuntu:~/linux_c/mmap$ gcc -o read read.c && ./read hello

6  zhangs 6  g

5  zhangs 5  f

4  zhangs 4  e

3  zhangs 3  d

2  zhangs 2  c

1  zhangs 1  b

0  zhangs 0  a

0  zhangs 0  a

0  zhangs 0  a

0  zhangs 0  a

chunli@ubuntu:~/linux_c/mmap$

写端:

chunli@ubuntu:~/linux_c/mmap$ cat write.c

#include

#include

#include

#include

#include

#include

#include

#include

#define SIZE 128//缓冲区128字节

void sys_err(char *p,int exitno)

{

perror(p);

exit(exitno);

}

struct Stu

{

int id;

char name[20];

char sex;

};

int main(int argc,char **argv)

{

if(argc

{

printf("参数不够\n");

exit(1);

}

//创建文件

int fd = open(argv[1],O_RDWR | O_CREAT ,0777);

if(fd == -1)

{

sys_err("open",1);

}

lseek(fd,SIZE -1 ,SEEK_SET);

write(fd,"\0",1);

//自动分配地址空间,申请len的字节,读写模式,fd文件,0偏移

struct Stu *p = mmap(NULL,SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

if(p == MAP_FAILED)//检查映射是否成功

{

sys_err("mmap",3);

}

close(fd);//关闭关联的文件,内存映射依然可对其读写

//修改文件的值

int i = 10;

while(i--)

{

p->id  = i;

sprintf(p->name,"zhangs %d",i);

p->sex = 0x61 + i;

sleep(1);

}

unlink(argv[1]);//删除临时文件

munmap(p,SIZE);//避免内存泄漏

return 0;

}

chunli@ubuntu:~/linux_c/mmap$ gcc -o write write.c  && ./write hello

chunli@ubuntu:~/linux_c/mmap$

确实没有了临时文件

chunli@ubuntu:~/linux_c/mmap$ ll

总用量 32K

-rwxrwxr-x 1 chunli chunli 8.9K 8月  10 21:30 read*

-rw-rw-r-- 1 chunli chunli 1008 8月  10 19:45 read.c

-rwxrwxr-x 1 chunli chunli 9.0K 8月  10 21:30 write*

-rw-rw-r-- 1 chunli chunli 1.1K 8月  10 21:29 write.c

chunli@ubuntu:~/linux_c/mmap$

作业:自己写一个 shell程序

用讲过的各种C函数实现一个简单的交互式Shell,要求:

1、给出提示符,让用户输入一行命令,识别程序名和参数并调用适当的exec函数执行

程序,待执行完成后再次给出提示符。

2、识别和处理以下符号:

简单的标准输入输出重定向:仿照例 “wrapper”,先dup2然后exec。

管道(|):Shell进程先调用pipe创建一对管道描述符,然后fork出两个子进程,一个

子进程关闭读端,调用dup2把写端赋给标准输出,另一个子进程关闭写端,调用dup2把读端

赋给标准输入,两个子进程分别调用exec执行程序,而Shell进程把管道的两端都关闭,调

用wait等待两个子进程终止。

你的程序应该可以处理以下命令:

○ls△-l△-R○>○file1○

○cat○○file1○

○表示零个或多个空格,△表示一个或多个空格

项目3步走 1.实现加载普通命令 2.实现重定向的功能 3.实现管道 4.实现多重管道支持

linux+mmap父子通信_Linux 系统开发5 进程间通信 pipe() fifo() mmap()相关推荐

  1. linux+mmap父子通信_linux库函数mmap()原理?转载

    linux库函数mmap()原理 转载 1.mmap基本概念 2.mmap内存映射原理 3.mmap和常规文件操作的区别 4.mmap优点总结 5.mmap相关函数 6.mmap使用细节 7.mmap ...

  2. Linux的基础知识——mmap父子通信进程和匿名通信

    1.mmap父子进程通信 \qquad父子等有血缘关系的进程之间也可以通过mmap建立的映射区来完成数据通信.但相应的要在创建映射区时候指定对应的标志位参数flags: \qquadMAP_PRIVA ...

  3. linux系统编程_Linux系统编程:进程间通信

    进程的重要性对于编程人员来说,至关重要,那么,进程间是如何通信的呢?在一个大的项目中,进程间的通信有哪些方式,这对于我们程序员来说也是很重要的一个点?那么本节我们就来聊聊进程间通信的方式,以及各自的优 ...

  4. linux漏洞知乎_linux系统怎么用

    laonanhai123 发表了文章 • 0 个评论 • 1911 次浏览 • 2020-09-14 16:43 • 来自相关话题 随着开源软件影响力的日益增强,Linux服务器操作系统在整个服务器操 ...

  5. linux挂载移动硬盘 格式化_linux系统下如何挂载NTFS移动硬盘

    前言 数据迁移是我们经常会遇到的,有时候做大数据量迁移时,为了快速迁移大数据,有可能在Linux服务器上临时挂载NTFS格式的移动硬盘, 一般情况下,Linux是识别不了NTFS格式移动硬盘的(需要重 ...

  6. guid linux 识别的分区表_Linux系统MBR和GPT分区的区别介绍

    主引导记录(Master Boot Record , MBR)是指一个存储设备的开头 512 字节.它包含操作系统的引导器和存储设备的分区表. 全局唯一标识分区表(GUID Partition Tab ...

  7. linux @webserviceclient 访问超时_Linux系统调优

    linux系统linux系统安装完毕后,首先要做的就是系统调优,这样会提高系统的使用效率,接下来为大家介绍一下linux系统调优方法.linuxlinux系统安装完毕后,首先要做的就是系统调优,这样会 ...

  8. linux java进程消失_Linux系统下的Java进程无故消失怎么办?

    Linux系统步骤的一些Java项目总是无故的消失,原来是Java进程被关闭掉了.为什么会出现这种情况呢?有可能是被系统自动清除多余进程,或是其他程序关掉了Java项目,这个时候该怎么办呢? 解决方法 ...

  9. linux ftp下载文件_Linux系统中10个使用Wget命令下载文件示例

    wget 是一个从网络上自动下载文件的命令行工具,支持通过 HTTP.HTTPS.FTP 三个最常见的 TCP/IP协议 下载,并可以使用 HTTP 代理.它是一个非交互式工具,非常适合通过脚本或者在 ...

  10. linux 删除文件命令_Linux系统常用的文件管理命令

    请关注本头条号,每天坚持更新原创干货技术文章. 如需学习视频,请在微信搜索公众号"智传网优"直接开始自助视频学习 1. 前言 本文主要讲解在Linux系统中,常用的文件管理工具有哪 ...

最新文章

  1. 浅谈 PHP 神盾的解密过程
  2. Python Number(数字)
  3. The Way to TiDB 3.0 and Beyond (下篇)
  4. 在做自动化测试之前你需要知道的,转自:http://www.cnblogs.com/fnng/p/3653793.html
  5. C语言中低位存放,C语言 大端小端存储解析以及判断方法
  6. 驳AXAJ的七宗罪 (转)
  7. Nacos(二)之概念
  8. 标准WPS框架下的空间信息处理服务部署方法
  9. 循序渐进之Maven(4) - 第一个SpringMVC项目
  10. c语言实现点在多边形内部,求教这个判断点是否在多边形内的C语言算法用的什么原理....
  11. 用于 Windows8 的 Wijmo Charts 图表控件
  12. 在WebClient类中保持Session
  13. 阶段3 2.Spring_07.银行转账案例_9 基于子类的动态代理
  14. ArcPad 10 使用与同步 ArcGIS Server 的数据全攻略(二)
  15. 刚体运动学公式_经典运动学公式汇总
  16. Error: PostCSS received undefined instead of CSS string核心解决方法
  17. 设计模式——设计模式名中英文对照
  18. 传感器实训心得体会_生产线实习心得体会范文
  19. 在Kmplayer中添加sub字幕过大而挡住视频的解决方法
  20. STM32单片机学习(11) DS18B20温度传感器实验

热门文章

  1. BZOJ2748[HAOI2012] 音量调节
  2. fastmock模拟常见数据结构
  3. ntpdate 时间同步
  4. 微信小程序获取是android还是ios,微信小程序-手机操作系统以及微信版本判断
  5. 用java怎么让时间走动起来,java脚本实现时间刷新
  6. MyBatis常见问题和解决方法
  7. 软件测试算是后端吗,软件测试--前后端数据交互
  8. Docker从理论到实践(九)------使用Dockerfile创建镜像
  9. (7)Spring框架----面向切面编程(一个简单的约定游戏)
  10. [CQOI 2018]交错序列