2018-2019-1 20165212 《信息安全系统设计基础》第八周学习总结(pwd)

时间:2021-01-31 16:37:21

2018-2019-1 20165212 《信息安全系统设计基础》第八周学习总结


一、知识点总结

1、三种并发方式

构造并发程序的方法有三种:

  • 进程
  • 线程
  • I/O多路复用

进程:用内核来调用和维护,有独立的虚拟地址空间,显式的进程间通信机制。

线程:运行在一个单一进程上下文中的逻辑流。由内核进行调度,共享同一个虚拟地址空间。

I/O多路复用:应用程序在一个进程的上下文中显式地调度控制流。逻辑流被模型化为状态机。

2、C/S编程模型

客户端和服务器都是进程,C/S编程模型由一个服务器进程和一个或多个客户端进程组成

服务器进程管理某种资源,通过操作这种资源来为它的客户端提供某种服务。基本操作为事务,一个客户端-服务器事务由四步组成:

  • 客户端向服务器发送请求,发起一个事务;
  • 服务器收到请求,操作资源;
  • 服务器给客户端发送一个响应,并等待下一个请求。
  • 客户端收到响应并处理它。

3、线程控制及相关系统调用

socket编程中:线程是运行子进程上下文中的逻辑流

线程与进程的不同

  • 线程的上下文切换要比进程的上下文切换快得多;
  • 和一个进程相关的线程组成对等,独立于其他线程创建的线程。
  • 主线程和其他线程的区别仅在于它总是进程中第一个运行的线程。

创建线程

  • pthread create:创建一个新的线程,在新线程的上下文中运行线程例程f。
  • 新线程可以通过pthread _self获得自己的线程ID。

终止线程

  • 一个线程的终止方式:当顶层的线程例程返回,线程会隐式地终止;
  • pthread_exit:线程显式地终止。

注:如果主线程调用pthread _exit,它会等待所有其他对等线程终止,然后再终止主线程和整个进程。

回收已终止线程的资源

  • pthread _join:阻塞,直到线程tid终止,回收已终止线程占用的所有存储器资源。

注:pthread _join只能等待一个指定的线程终止。

分离线程

  • 在任何一个时间点上,线程是可结合的或者是分离的。一个可结合的线程能够被其他线程收回其资源和杀死;一个可分离的线程是不能被其他线程回收或杀死的。它的存储器资源在它终止时有系统自动释放。
  • 默认情况下,线程被创建成可结合的,为了避免存储器漏洞,每个可集合的线程都应该要么被其他进程显式的回收,要么通过调用pthread _detach被分离。

初始化线程 pthread _once允许初始化与线程例程相关的状态。once _control变量是一个全局或者静态变量,总是被初始化为PTHREAD _ONCE _INIT。

二、通过系统调用实现-pwd命令

步骤:

  • 学习 pwd 命令
  • 研究实现 pwd 所需要的系统调用

pwd是将当前的文件目录的绝对路径打印出来,所以要找到一个函数可以返回当前文件目录名。所以在命令行中输入 man -k dir | grep get 得到如下的信息: 2018-2019-1 20165212 《信息安全系统设计基础》第八周学习总结(pwd)

如上图:getwd正是我们所需要的,通过命令输入: man getwd 得到如下信息:

2018-2019-1 20165212 《信息安全系统设计基础》第八周学习总结(pwd)

2018-2019-1 20165212 《信息安全系统设计基础》第八周学习总结(pwd)

显然, getwd() 函数功是将当前工作目录的绝对路径复制到数组指针buf中。但是以上代码过于简单,所以按照要求:通过操作目录文件来进行实现 pwd 功能。 思路:

  • 1.打开文件目录查看所有目录如果查到当前目录中有两个相同的" ."文件说明已经到了文件根目录,也就是说本目录的i-node与上级目录的i-- node相同。
  • 2.否则进入".."文件目录,并且将上一级件目录名记录添加到数组中
  • 3.直到符合1的条件为止

具体操作:

  • 命令行输入 man -k open | grep dir 找到了符合条件的函数: opendir 。
  • 需要读取目录的信息——输入 man -k read | grep dir ,找到符合条件的函数: readdir
  • 结束需要关闭文件目录流 man -k close | grep dir ,找到符合条件的函数: readdir
  • 通过 man opendir , man readdir,man closedir 等得知各个函数所需的头文件以及函数参数

对于读取文件目录流涉及到一个结构体:

struct dirent{
ino_t d_ino;//文件结点号
off_t d_off;
unsigned short d_reclen;
unsigined char d_type;
char d_name[];//文件名
}

man -k dir | change 查到fchdir函数: change working directory;

man- k dir 查到chdir作用也是change working directory

比较:

2018-2019-1 20165212 《信息安全系统设计基础》第八周学习总结(pwd)

意思是:fchdir用的时候会把当前目录作为打开的文件描述符给出(还不明白)

百度之后查到:fchdir函数传入值是指针fd,函数功能是将当先工作目录改变为fd指的getcwd(gwtcwd函数执行会打印当前文件夹,时间关系,最后打印出来的东西是傻还bzd),但可以肯定的是肯定用的是chdir了。

代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h> ino_t get_inode(char*);
void printpathto(ino_t);
void inode_to_name(ino_t,char*,int);
int main()
{
printpathto(get_inode(".")); //print path to here
putchar('\n');
return ;
} void printpathto(ino_t this_inode)
{
ino_t my_inode;
char its_name[BUFSIZ];
/*如果本目录的i-节点与上级目录不同,即本目录不是根目录*/
if (get_inode("..")!=this_inode)
{
chdir(".."); //进入上级目录
inode_to_name(this_inode,its_name,BUFSIZ);
my_inode = get_inode(".");
printpathto(my_inode);
printf("/%s",its_name);
}
}
void inode_to_name(ino_t inode_to_find,char* namebuf,int buflen) //找到i-节点对应的文件名,并放在字符数组里
{
DIR* dir_ptr;
struct dirent* direntp;
dir_ptr = opendir(".");
if (dir_ptr == NULL)
{
perror(".");
exit();
}
/*上面是打开一个目录流,然后下面是通过目录流读取来查找当前目录的与要找的i-node相对应的文件名,之后关闭目录流*/
while((direntp = readdir(dir_ptr)) != NULL)
{
if(direntp->d_ino == inode_to_find)
{
strncpy(namebuf,direntp->d_name,buflen);
namebuf[buflen-] = '\0';
closedir( dir_ptr);
return;
}
}
fprintf( stderr , "error looking for inum % d\n" ,inode_to_find);
exit () ;
}
ino_t get_inode(char* fname)//根据文件名,返回-i节点
{
struct stat info;
if ( stat( fname, &info) == -){
fprintf( stderr , "Cannot stat ");
perror(fname);
exit ();
}
return info.st_ino;
}

实验截图:

2018-2019-1 20165212 《信息安全系统设计基础》第八周学习总结(pwd)


本周学习感想

上课的时候认真听了一段时间,就是讲 如找上级目录的那一部分,我有想到找.和..目录以及i节点匹配 ,但是结束的时候怎么办没想清楚,以后再学习计算机系统结的时候还需要更强的计算机思维