关于linux的几道题,你能回答几个?--回答1~13题

1.memcmp可否用来比较结构体?strcmp和memcpy的区别?

参考:http://www.cnblogs.com/cxz2009/archive/2010/11/11/1875125.html

[email protected]:/study/linuxknowledge# cat memcmptest.c

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

typedef struct CmpTest
{
char  a;
short b;
int   c;
}CmpTest;

int main(int argc, char *argv[])
{
CmpTest t1, t2;
printf("%d\n", memcmp(&t1, &t2, sizeof(CmpTest)));

CmpTest t3, t4;
memset(&t3, 0, sizeof(CmpTest));
memset(&t4, 0, sizeof(CmpTest));
printf("%d\n", memcmp(&t3, &t4, sizeof(CmpTest)));

t1.a = 'a';
t1.b = 3;
t1.c = 5;
t2.a = 'a';
t2.b = 3;
t2.c = 5;

printf("%d\n", memcmp(&t1, &t2, sizeof(CmpTest)));
t3.a = 'a';
t3.b = 3;
t3.c = 5;

t4.a = 'a';
t4.b = 3;
t4.c = 5;
printf("%d\n", memcmp(&t3, &t4, sizeof(CmpTest)));
t2 = t1;
printf("%d\n", memcmp(&t1, &t2, sizeof(CmpTest)));

t4 = t3;
printf("%d\n", memcmp(&t3, &t4, sizeof(CmpTest)));

return 0;
}

[email protected]:/study/linuxknowledge# ./memcmptest

1

0

1

0

0

0

[email protected]:/study/linuxknowledge#

也就是说:如果初始化赋初值(memset),则是可以相比较的

另外,如果使用“=”号赋值,两个结构是会相等的

但是,如果结构没有赋初值,即使各变量赋值相同,memcmp比较的结果仍不同。

另外,即使比较结果相同,也不能说明这两个结构体是相同的,只是结构体这么大块的内存中的内容是相同,因为可能成员不同。

2.软中断和硬中断的区别?

(1)硬中断为硬件产生中断信号,CPU相应中断信号;而软中断与硬件无关,由CPU调度。比如产生一个EXT中断或者MSI中断、Mailbox中断等,触发CPU来响应,这是硬中断。软中断一般作为中断的下半部来处理,CPU在中断处理函数的上半部处理需要尽快完成的工作,然后由内核来调度下半部的执行,这里的下半部可以使用软中断来实现,或者tasklet、workqueue来实现。

(2)软中断一般是处理I/O请求,不会中断CPU,由内核调度。而硬中断一般是响应硬件中断信号,会中断CPU,会触发内核中的中断函数。流程上,软中断从进程切换到驱动程序,而硬中断会是硬件->CPU->中断处理函数。

3.进程间通信的几种方式?哪种效率最高?

(1)管道PIPE和有名管道FIFO -- 比如shell的重定向

(2)信号signal -- 比如杀死某些进程kill -9,比如忽略某些进程nohup ,信号是一种软件中断

(3)消息队列 -- 相比共享内存会慢一些,缓冲区有限制,但不用加锁,适合命令等小块数据。

(4)共享内存 -- 最快的IPC方式,同一块物理内存映射到进程A、B各自的进程地址空间,可以看到对方的数据更新,需要注意同步机制,比如互斥锁、信号量。适合传输大量数据。

(5)信号量 -- PV操作,生产者与消费者示例

(6)套接字 -- socket网络编程

如下参考:http://blog.csdn.net/piaoairy219/article/details/17333691

------管道

管道的优点是不需要加锁,缺点是默认缓冲区太小,只有4K,同时只适合父子进程间通信,而且一个管道只适合单向通信,如果要双向通信需要建立两个。而且不适合多个子进程,因为消息会乱,它的发送接收机制是用read/write这种适用流的,缺点是数据本身没有边界,需要应用程序自己解释,而一般消息大多是一个固定长的消息头,和一个变长的消息体,一个子进程从管道read到消息头后,消息体可能被别的子进程接收到

------消息队列

消息队列也不要加锁,默认缓冲区和单消息上限都要大一些,在我的suse10上是64K,它并不局限于父子进程间通信,只要一个相同的key,就可以让不同的进程定位到同一个消息队列上,它也可以用来给双向通信,不过稍微加个标识,可以通过消息中的type进行区分,比如一个任务分派进程,创建了若干个执行子进程,不管是父进程发送分派任务的消息,还是子进程发送任务执行的消息,都将type设置为目标进程的pid,因为msgrcv可以指定只接收消息类型为type的消息,这样就实现了子进程只接收自己的任务,父进程只接收任务结果

------共享内存

共享内存的几乎可以认为没有上限,它也是不局限与父子进程,采用跟消息队列类似的定位方式,因为内存是共享的,不存在任何单向的限制,最大的问题就是需要应用程序自己做互斥,有如下几种方案

1 只适用两个进程共享,在内存中放一个标志位,一定要声明为volatile,大家基于标志位来互斥,例如为0时第一个可以写,第二个就等待,为1时第一个等待,第二个可以写/读

2 也只适用两个进程,是用信号,大家等待不同的信号,第一个写完了发送信号2,等待信号1,第二个等待信号2,收到后读取/写入完,发送信号1,它不是用更多进程是因为虽然父进程可以向不同子进程分别发送信号,但是子进程收到信号会同时访问共享内存,产生不同子进程间的竞态条件,如果用多块共享内存,又存在子进程发送结果通知信号时,父进程收到信号后,不知道是谁发送,也意味着不知道该访问哪块共享内存,即使子进程发送不同的结果通知信号,因为等待信号的一定是阻塞的,如果某个子进程意外终止,父进程将永远阻塞下去,而不能超时处理

3 采用信号量或者msgctl自己的加锁、解锁功能,不过后者只适用于linux

4.kmalloc和vmalloc差别?

kmalloc映射的是先行区的物理内存,vmalloc映射的是非线性区的物理内存,或者说高端内存区的物理内存。因为vmalloc是映射的非线性区,所以申请大块内存时更容易成功。而kmalloc由于申请连续物理内存,由于内存空洞等原因,申请较大块的内存容易失败,可以根据伙伴系统中的大块内存使用情况来决定是否可使用kmalloc申请。

Kmalloc、get_free_pages申请的是先行区内存

Ioremap、vmalloc申请的是vmalloc区域,或者说高端内存区、非线性映射区的内存。

5. 应用层的mmap、malloc和内核态的vmalloc对内存访问的差别?

应用层的mmap用来映射文件,malloc用来动态分配内存

Mmap并不分配实际的物理空间,只是将文件映射到调用进程的虚拟地址空间。

Malloc、vmalloc分配实际的物理内存

6.用户态是否可以直接访问内核态内存?

一种比较常用的实现内核态和用户态进程共享内存的方法。内核态: 内核态分配内存(可用页__get_free_page),然后将分配内存的虚拟地址写到注册的proc文件系统中。用户态: 首先根据proc文件系统获得内核态分配内存的虚拟地址,将该地址转换为实际的物理地址,通过映射/dev/mem,对物理地址进行访问。另一个例子是帧缓存,也是从用户态访问内核态内存的例子。

7. PCIe中MSI中断如何触发?

通过访问MSI Capabilitiy结构中的address、data,向MSI address中写入MSI data来触发对端的MSI中断

8.怎么知道一个文件的大小?

多种方式:

(1)尾指针减去头指针:

unsigned long get_file_size(const char *path)
{
    unsigned long filesize = -1;
    FILE *fp;
    fp = fopen(path, "r");
    if(fp == NULL)
        return filesize;
    fseek(fp, 0L, SEEK_END);
    filesize = ftell(fp);
    fclose(fp);
    return filesize;
}  

(2)读取文件属性

#include <sys/stat.h>  

unsigned long get_file_size(const char *path)
{
    unsigned long filesize = -1;
    struct stat statbuff;
    if(stat(path, &statbuff) < 0){
        return filesize;
    }else{
        filesize = statbuff.st_size;
    }
    return filesize;
}  

9.spin_lock和mutex_lock的区别?spin_lock在单核和多核模式下的区别?

Spin_lock和Mutexock:(参考http://blog.csdn.net/wilsonboliu/article/details/19190861)

互斥锁mutex_lock是sleep-waiting。 就是说当没有获得mutex时,会有上下文切换,将自己、加到忙等待队列中,直到另外一个线程释放mutex并唤醒它,而这时CPU是空闲的,可以调度别的任务处理。

自旋锁spin lock是busy-waiting。就是说当没有可用的锁时,就一直忙等待并不停的进行锁请求,直到得到这个锁为止。这个过程中cpu始终处于忙状态,不能做别的任务。(疑问:这不死锁了么?)例如在一个双核的机器上有两个线程(线程A和线程B),它们分别运行在Core0 和Core1上。 用spin-lock,coer0上的线程就会始终占用CPU。

另外一个值得注意的细节是spin lock耗费了更多的user time。这就是因为两个线程分别运行在两个核上,大部分时间只有一个线程能拿到锁,所以另一个线程就一直在它运行的core上进行忙等待,CPU占用率一直是100%;而mutex则不同,当对锁的请求失败后上下文切换就会发生,这样就能空出一个核来进行别的运算任务了。

如何选择?

(1)Mutex适合对锁操作非常频繁的场景,并且具有更好的适应性。尽管相比spin lock它会花费更多的开销(主要是上下文切换),但是它能适合实际开发中复杂的应用场景,在保证一定性能的前提下提供更大的灵活度。

(2)spin lock的lock/unlock性能更好(花费更少的cpu指令),但是它只适应用于临界区运行时间很短的场景。而在实际软件开发中,除非程序员对自己的程序的锁操作行为非常的了解,否则使用spin lock不是一个好主意(通常一个多线程程序中对锁的操作有数以万次,如果失败的锁操作(contended lock requests)过多的话就会浪费很多的时间进行空等待)。

(3)更保险的方法或许是先(保守的)使用 Mutex,然后如果对性能还有进一步的需求,可以尝试使用spin lock进行调优。毕竟我们的程序不像Linux kernel那样对性能需求那么高(Linux Kernel最常用的锁操作是spin lock和rw lock)。

Spin_lock在单核、多核上的差异:(参考http://blog.chinaunix.net/uid-25871104-id-3052138.html)

Spin_lock是Linux内核的一种同步机制。内核代码可以通过获得spin_lock宣称对某一资源的占有,直到其释放该spin_lock;如果内核代码试图获得一个已经锁定的spin_lock,则这部分代码会一直忙等待,直到获得该spin_lock。

spin_lock在单核多核下的不同:

Spin_lock的kernel中的实现对单核(UP),多核(SMP)有不同的处理方式。对单核来说,如果spin_lock不处于中断上下文,则spin_lock锁定的代码丢失CPU拥有权,只会在内核抢占的时候发生。所以,对于单核来说,只需要在spin_lock获得锁的时候禁止抢占,释放锁的时候开放抢占。对多核来说,存在两段代码同时在多核上执行的情况,这时候才需要一个真正的锁来宣告代码对资源的占有。

10.多进程时wait用来干什

(参考http://blog.csdn.net/wallwind/article/details/6998602)

等待子进程执行完毕:如果其所有子进程都在运行,则阻塞;如果一个子进程已经终止,正在等待的父进程获取到终止状态,则取得该子进程的终止状态立即返回;如果他没有任何子进程,则立即出错返回。

11. 进程如果卡住,如何查看卡在哪里?

(1)通过魔术键打印此时堆栈信息

(2)通过gdb打印堆栈信息

该问题没什么思路,求大神指导

12 .宕机问题如何排查?(参考http://blog.chinaunix.net/uid-25909722-id-3047986.html)

(1)查看message信息(/var/log/messages,最好重定向或配置保存到flash中,以便重启分析)

(2)魔术键查看是否系统有响应,如有响应分析魔术键盘触发的各种信息

(3)开启内核lock检测配置

这个问题也请大神指导下,思路比较有限

13.可变参数的原理?应该如何实现?(参考:http://blog.csdn.net/wooin/article/details/697106)

[email protected]:/study/linuxknowledge# cat vaarg.c

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void simple(int i, ...)
{
va_list arg_ptr;
char *s = NULL;

va_start(arg_ptr, i);
s = va_arg(arg_ptr, char *);
va_end(arg_ptr);

printf("%d %s\n", i, s);

return ;
}

int main(int argc, char *argv[])
{
int i = 10;
simple(i, "hello ni ma!\n");

return 0;
}

[email protected]:/study/linuxknowledge# ./vaarg

10 hello ni ma!

[email protected]:/study/linuxknowledge#

简单说就是用va_arg宏来实现的,va_arg宏,详情请看http://blog.csdn.net/wooin/article/details/697106

进一步的探索后面再写

时间: 2024-10-12 18:28:58

关于linux的几道题,你能回答几个?--回答1~13题的相关文章

关于linux的几道题,你能回答几个?--回答21-25题

21. 如何进行性能优化.如何增加开机速度? 21.1 性能优化绝对是一个非常大的问题,影响性能的地方太多,参考如下专题: http://www.it168.com/redian/linuxmr/ 如果面试官问你的思路,那么可以参考: 首先,优化的目的是什么?或者说优化的指标是什么? (参考http://blog.chinaunix.net/uid-7177878-id-252142.html) (1)处理器参数 这是一个很简单的参数,它直观的描述了每个CPU的利用率.在xSeries架构中,如

关于linux的几道题,你能回答几个?--回答14-20题

14.select和poll的区别?Poll和epoll的区别? (1)select和poll的区别:(参考:http://blog.csdn.net/mituan2008/article/details/6695177) 二者根本的不同是:select()的fd_set是一个位掩码(bit mask),因此fd_set有固定的长度.内核在被编译的时候,可以不受这个长度的限制,因为select()允许应用程序自定义FD_SETSIZE的大小,但是这会增加额外的支出. 在调用poll()时需要自定

关于linux的几道题,你能回答几个?

1.memcmp可否用来比较结构体?strcmp和memcpy的区别? 2.软中断和硬中断的区别? 3.进程间通信的几种方式? 4.kmalloc和vmalloc差别? 5.应用层的mmap和内核态的vmalloc对内存访问的差别? 6.用户态是否可以直接访问内核态内存? 7.PCIe中MSI中断如何触发? 8.怎么知道一个文件的大小? 9.spin_lock在单核和多核模式下的区别? 10.多进程时wait用来干什么? 11.进程如果卡住,如何查看卡在哪里? 12.宕机问题如何排查? 13.可

Linux中PHP安装与配置(CentOS-6.5:php-5.2.13)

1 PHP简介 PHP(PHP: Hypertext Preprocessor的缩写,中文名:"超文本预处理器")是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,入门门槛较低,易于学习,使用广泛,主要适用于Web开发领域.PHP的文件后缀名为php. 2 下载地址 1)libmcrpyt ftp://mcrypt.hellug.gr/pub/crypto/mcrypt/libmcrypt/libmcrypt-2.5.7.tar.gz 2) php http://ww

【Linux下禁用rm命令之建立回收站】 -- 2019-08-11 19:13:54

原文: http://106.13.73.98/__/86/ 第一步 创建回收站目录 # 根据自己的习惯,找个位置创建一个用作回收文件的目录 # 我们这里将在root目录下面创建一个名为".trash"的隐藏文件 [[email protected] ~]# mkdir .trash 第二步 创建回收站脚本文件 # 同样是根据自己的习惯找个位置创建 [[email protected] ~]# vim .remove.sh 打开后在文件内写入如下代码: # 指定第一步骤中创建的回收站目

Linux入门之CentOS7内核编译三部曲(1)

Linux入门之CentOS7内核编译三部曲(1) 我们知道,一个Linux系统的主要组成是由liunx内核核心和一些支持模块组合而成的.但是在某些场合中,需要某项功能,而当前内核的核心或者模块不支持此功能,那么就需要对内核进行一个升级或者重新编译内核添加相应的功能,以此提供了对此功能的支持. 编译前的准备 认识kernel 所为kernel,就是一种操作系统的核心,当然也是一个文件,而这种核心提供了对一些硬件的支持,一般来说其中包含了一些对常见硬件核心驱动的核心代码.启动系统时会通过加载MBR

linux磁盘管理和文件系统创建

1      磁盘管理 1.1    硬盘的构造原理 硬盘分类: 机械式硬盘,固态硬盘 硬盘出厂会进行低级格式化,分磁盘,再分扇区,硬盘的第一个磁道的一个扇区就是MBR 512Bytes Master boot record 446 bytes bootloader 主引导程序 64bytes :主分区存储 16bytes表示一个主分区,最多4个主分区 2bytes:magic number 表示mbr是否有效 硬盘的注意事项: a)                1.硬盘需要绝对的无尘环境,生

linux总结应用之三 建立内核

          建立内核  (1):第一:检验linux源程序是否已在 /usr/include 目录中建立了两个符号连接: #   cd /usr/include #   ls  -l  asm  linux lrwxrwxrwx    1  root   root  26 Jul  4  17:27   asm -> /usr/src/linux /include/asm lrwxrwxrwx    1  root   root  28  Jul  4 17:27    linux->

Linux下磁盘分区、文件管理工具详解

一.规划磁盘分区:fdisk 二.格式化磁盘分区:mkfs.xxx 三.文件系统管理:blkid.e2label.tune2fs 四.创建swap分区:mkswap 五.文件系统的检测:fsck 一:规划磁盘分区 测试环境:CentOS 6.6 1.查看磁盘分区 格式:fdisk -l [磁盘名] 示例: [[email protected] ~]# fdisk -l /dev/sda     //如果不指出磁盘名,会列出所有磁盘分区信息 Disk /dev/sda: 107.4 GB, 107