ssh远程链接不上虚拟机解决方案
先查看是否在同一网段 windos-cmd- ipconfig /all
ping 虚拟机上的ip 查看是否ping通 不能ping通执行一下操作
查看以太网和虚拟机上的网段是否是相同的 ip前三个字段
如果不等就是不在同一网段
控制面板-网络连接-网络适配器-更改网络适配器设置
将本机的ip改成虚拟机上前面三个字段相同的ip
ifdwn eth0
//关闭网络
ifup eth0
//启动网络 //如果还不行
虚拟机先关闭linux-编辑-虚拟网络编辑器-更改设置-还原默认设置
注 设置完成之后地址可能会发生变化
ps -ef grep 程序名
//输出这个程序的信息程序名写一半就是同名这一半的所有信息(当前运行的程序) 获取当前程序的进程id
ps -ef
//打印所有的进程信息 UID //进程的ID PPID 父进程的id
进入那个正在执行的程序的fd cd /proc/进程id/fd //就可以查看0表示标准输入(键盘),1表示标准输出(控制台),2表示标准错误 (控制台)
printf 另一种写法 write(1,"I love you",长度) ;
写道标准输出
文件操作
#include<unistd.h>
*write*//写文件
ssize_t write(int fd, const void *buf, size_t count);
第一个参数 写到文件描述句柄中(句柄)
第二个参数文件数据类型 ,
第三个参数是大小 成功返回字节数 失败返回-1错误编号设置 errno 可用( strerror(errno) ) 查看
注意:是从文件的当前指针位置写入!//刚打开时文件指针在文件头部
*read读文件*
ssize_t read(int fd, const void *buf, size_t count);
第一个参数从文件描述句柄中读,
第二个参数读到哪个位置,
第三个读的字节数
返回值 出错返回-1错误编号设置 errno 可用( strerror(errno) ) 查看,返回读到的字节数 0表示读到文件的末尾
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char buffer[1024];
int cnt = 0;//从标准输入中读取
cnt = read(0, buffer, sizeof(buffer));
write(1, buffer, cnt);//1表示标准输出(控制台)
return 0;
}
./程序名 < main.c
/* 利用重定向, 使用文件main.c作为输入 < 表示重定项
./程序名 < main.c
/* > 符号 表示往main.c 中写 在控制台输入之后不会显示到控制台 会直接写道 main.c中去*/
*open*
(1) 用法
#include <stdio.h>
#include<unistd.h>
#include <stdlib.h>
//open头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);//路径打开方式 | 符号可用多个方式打开 默认是读写 如果加第3个参数 那么表示权限
(2) 返回值
成功:文件描述符
失败:-1
(3) 打开方式
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_CREAT 如果文件不存在,则创建该文件,并使用第3个
参数设置权限,如果文件存在 ,则只打开文件
O_EXCL 如果同时使用O_CREAT而且该文件又已经存在
时,则返回错误, 用途:以防止多个进程同时创建//如果存在就打开失败
O_APPEND 尾部追加方式(打开后,文件指针指向文件的末尾)
O_TRUNC 若文件存在,则长度被截为0,属性不变
example: open("/dev/hello", O_RDONLY|O_CREAT|O_EXCL, 0777)
(4) 参数3 (设置权限)
当使用O_CREAT时,使用参数3
S_I(R/W/X)(USR/GRP/OTH)//详情 man 2 open
例:
S_IRUSR | S_IWUSR 文件的所有者对该文件可读可写
(八进制表示法)0600 文件的所有者对该文件可读可写
注意:
返回的文件描述符是该进程未打开的最小的文件描述符
*****\*close\******
close (int 文件句柄);
终止指定文件描述符与对应文件之间的关联, 并释放该文件描述符,即该文件描述符可被重新使用
返回值
成功: 0
失败: -1
***\*lseek\*//重新定义文件读和写的位置***
```c++
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
1文件句柄
2 偏移量多少位置
3相对哪里偏移 枚举参详 man lseek
返回值
成功:返回新的文件位置与文件头之间偏移
失败: -1
标准I/O库
//这些函数带缓冲功能,在执行系统调用时可以避免不必要的开销
/* C语言中的文件操作中已描述 */
1) fwrite //带缓冲的写,避免多次系统调用,可以提高效率
2) fread
3) fopen
4) fclose
5) fseek
6) fflush
//应用层和内存形成的读写被称为逻辑IO
//内存和物理内存形成的读写被称为物理IO(文件系统调用 “系统调用”)
标准IO
O_SYNC(open的时候加上)只对写数据有效,(利用写一点就同步的方式 直到写成功才返回)
它将写入内核缓冲区的数据立即写入磁盘,将机器故障时,
数据的丢失减少到最小,但是它仍然要经过内核缓冲区。(效率不高)
标准IO 缓存同步
-为了保证磁盘系统与缓冲区中内容一致,
Linux 系统提供了 sync、fsync 和fdatasync 三个函数.
向打开的文件写数据; 成功返回0 ,若出错,返回-1。
#include <unistd.h>
int fsync(int fd);
int fdatasync(int fd);
void sync(void);//这些函数是缓存同步,也就是说不O_SYNC那样写一点就缓存
//一点而是按照特定的算法 或者规定写一大块在进行缓存
sync -
将所有修改过的块缓冲区排入写队列,然后就返回,它并不等待实际写磁盘操作结束。这种方式不保证能完全写入到磁盘
fsync -
将fd对应文件的块缓冲区立即写入磁盘,并等待实际写磁盘操作结束返回。//这种方式保证数据成功写入到磁盘
fdatasync -
类似fsync,但只影响文件的数据部分。而除数据外,fsync 还会同步更新文件属性。//更加精确只针对文件的数据部分写入到磁盘
Linux中分为 标准IO和直接IO(不常用) 像 write等都属于标准IO
open +O_DIRECT = 绕过内核缓冲区的直接访问,便有效避免了CPU和内存的多余时间开销。
注意:直接I/O的缺点就是如果访问的数据不在应用程序缓存中,
那么每次数据都会直接从磁盘进行加载,这种直接加载会非常缓慢!
通常直接I/O跟异步I/O结合使用会得到较好的性能。
直接IO需 加#define _GNU_SOURCE 因为磁盘是扇区的,
不管是读写 必须是512个字节磁盘的特性 需malloc一个512的char数组
但这个数组的地址又必须要去是512的整数倍所以用另一个函数
posix_memalign(void**)&定义的char指针,512,512)
//生成一个地址是512整数倍的512个字节的空间
第3个参数是分配的空间 头文件stdlib.h 返回值成功返回0 失败返回非0 错误设置error
(主要要求必须是内存边界对齐,基于硬件开发,效率较低)
//读的时候文件大小也必须是512的整数倍
*proc文件系统*进程文件系统
/proc是一个特殊的文件系统,
该目录下文件用来表示与启动、内核相关的特殊信息
1) /proc/cpuinfo
CPU详细信息
2) /proc/meminfo
内存相关信息
3) /proc/version
版本信息
4) /proc/sys/fs/file-max
系统中能同时打开的文件总数
可修改该文件
5) 进程的相关信息
/proc/32689/ 表示指定进程(进程号为32689)的相关信息
6) cat /proc/devices
已分配的字符设备、块设备的设备号
*文件锁*
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
查看帮助 man 2 fcntl
struct flock //结构体
{
short l_type; /*F_RDLCK 读上锁, F_WRLCK/ 写上锁, or F_UNLCK解锁 */
off_t l_start; /*offset in bytes, relative to l_whence 相对于l_where的偏移量(字节) */
short l_whence; /*SEEK_SET起始位置, SEEK_CUR, or SEEK_END */
off_t l_len; /*length, in bytes长度锁多长的字节; 0 means lock to EOF 表示锁到文件的结尾*/
pid_t l_pid; /*returned with F_GETLK进程id */
}
l_type: 第一个成员是加锁的类型:只读锁,读写锁,或是解锁。
l_start和l_whence: 用来指明加锁部分的开始位置。
l_len: 是加锁的长度。
l_pid: 是加锁进程的进程id。
注 当两个进程都是读锁的时候,都可以成功
如果是 一读一写就会出问题,会被阻塞在当前位置
如果是 一写一读就会出问题,会被阻塞在当前位置
如果两个都是写锁那么也会被阻塞
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILE_NAME "test.txt"
int flock_set(int fd, int type)
{
printf("pid=%d into...\n", getpid());// 获取当前进程的id
//初始化这个结构体
struct flock flock;
memset(&flock,0,sizeof(struct flock));
fcntl(fd, F_GETLK, &flock);//查看文件是否有锁
if (flock.l_type != F_UNLCK) //判断该文件是否有所
{
if (flock.l_type == F_RDLCK) //如果文件有读上锁
{
printf("flock has been set to read lock by %d\n", flock.l_pid);
}
else if (flock.l_type == F_WRLCK) //如果文件有写上锁
{
printf("flock has been set to write lock by %d\n", flock.l_pid);
}
}
flock.l_type = type;//加锁方式
flock.l_whence = SEEK_SET;//起始位置
flock.l_start = 0;//相对起始位置偏移量
flock.l_len = 0; //锁整个文件
flock.l_pid = -1;//p id不需要设置
if (fcntl(fd, F_SETLKW, &flock) < 0)//F_SETLKW加锁
// 参数2 cmd 命令 F_GETLK、F_SETLK和F_SETLKW 获取锁 设置锁 同步设置锁
//对于存在的记录锁(也称为文件段或文件)
//地区锁)。第三个参数lock是一个指向结构的指针
//它至少有以下字段(未指定顺序)。
{
printf("set lock failed!\n");//加锁失败
return -1;
}
switch (flock.l_type) //获取设置的加锁的方式
{
case F_RDLCK:
printf("read lock is set by %d\n", getpid());//打印出当前进程的id//读上锁
break;
case F_WRLCK:
printf("write lock is set by %d\n", getpid());//写上锁
break;
case F_UNLCK:
printf("lock is released by %d\n", getpid());//解锁
break;
default:
break;
}
printf("pid=%d out.\n", getpid());
return 0;
}
int main(void)
{
int fd;
fd = open(FILE_NAME, O_RDWR|O_CREAT, 0666);//0666表示所有权限
if (fd < 0) {
printf("open file %s failed!\n", FILE_NAME);
}
//flock_set(fd, F_WRLCK);//写上锁 这里F_WRLCK不是cmd 这里是结构体的第一个参数
flock_set(fd, F_RDLCK);//读上锁
getchar();
flock_set(fd, F_UNLCK);//解锁
getchar();
close(fd);
return 0;
}
inode - “索引节点 返回文件的状态信息加粗样式”,
储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。每个inode都有一个号码,操作系统用inode号码来识别不同的文件。ls -i 查看inode 号
``
stat函数
作用:返回文件的状态信息
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
path:
文件的路径
buf:
传入的保存文件状态的指针,用于保存文件的状态
返回值:
成功返回0,失败返回-1,设置errno
struct stat {
dev_t st_dev; /* ID of device containing file//设备ID */
ino_t st_ino; /* inode number //inode 编号*/
mode_t st_mode; /* 表示 S_ISREG(st_mode) 这个函数返回真 是一个普通文件 ,S_ISDIR(st_mode) 这个函数返回真是一个目录*/
nlink_t st_nlink; /* number of hard links//硬链接的数量 */
uid_t st_uid; /* user ID of owner//用户id*/
gid_t st_gid; /* group ID of owner //文件的组*/
dev_t st_rdev; /* device ID (if special file) //设备id*/
off_t st_size; /* total size, in bytes //文件的总大小*/
blksize_t st_blksize; /* blocksize for filesystem I/O//文件占的块的大小 */
blkcnt_t st_blocks; /* number of 512B blocks allocated //文件占的块的数量*/
time_t st_atime; /* time of last access //文件最近访问时间 */
time_t st_mtime; /* time of last modification //上次被修改的时间*/
time_t st_ctime; /* time of last status change //最近状态改变的时间*/
};