设为首页 加入收藏

TOP

操作系统6道面试题(一)
2023-07-23 13:36:40 】 浏览:53
Tags:

20230321

1.进程和线程的区别

进程(Process)和线程(Thread)是操作系统中的两个重要概念。

一个进程可以看作是一个正在运行的程序实例,它拥有自己的地址空间、内存、数据栈和其他系统资源。一个进程可以包含多个线程,每个线程都是进程中独立的执行流,每个线程共享进程的地址空间和系统资源。

线程是进程中的一个执行单元,它是操作系统调度的最小单位,不同的线程可以并行执行,从而提高了程序的并发性和效率。线程比进程更轻量级,创建和销毁的开销更小,也更容易实现线程间的通信和同步。

因此,进程和线程的主要区别如下:

  • 资源占用:进程是资源分配的最小单位,而线程是CPU调度的最小单位。每个进程都有自己的地址空间和系统资源,而多个线程共享进程的资源。

  • 通信和同步:不同进程之间通信和同步的成本比较高,而线程之间可以通过共享进程的内存空间实现通信和同步,成本更低。

  • 切换开销:由于每个进程都拥有自己的地址空间和系统资源,因此进程间的切换开销比线程更大。

  • 安全性:由于每个进程都拥有自己的地址空间和系统资源,因此进程间的安全性比线程更高。如果一个线程崩溃,会影响整个进程的稳定性,而一个进程崩溃只会影响自己。

总的来说,进程和线程都是并发编程中重要的概念,它们各有优缺点,需要根据具体的场景选择使用。

2.描述系统调用的整个流程

系统调用是操作系统提供给应用程序使用的接口,它允许应用程序通过操作系统内核来访问底层资源和功能。下面是系统调用的一般流程:

应用程序执行系统调用指令。这个指令将控制权转移到操作系统内核。

操作系统内核处理系统调用。这包括验证参数、权限检查、资源分配等操作,确保应用程序请求的操作是安全和合法的。

操作系统内核执行请求的操作。这可能涉及到与硬件交互,或者对某些内核数据结构进行操作,如文件描述符、进程控制块等。

操作系统内核将结果返回给应用程序。这个过程可能涉及到复制数据到应用程序的内存空间,或者简单地返回一个状态码。

应用程序恢复控制权,并继续执行。

需要注意的是,系统调用是一种开销较大的操作。当应用程序频繁调用系统调用时,会带来较大的性能开销。为了优化性能,一些操作系统提供了用户空间库,它们可以将多个系统调用合并为一个系统调用,或者将一些系统调用通过其他方式实现。

3.malloc 是如何分配内存的

malloc() 是 C 标准库中的函数,用于在程序运行时动态地分配内存。它的原型如下:

void* malloc(size_t size);

其中,size 参数指定要分配的内存大小,以字节为单位。

malloc() 函数的具体实现是由操作系统提供的,不同的操作系统可能有不同的实现方式。

一般来说,malloc() 函数使用一个空闲链表来管理可用的内存块。当程序调用 malloc() 函数时,它会在链表中寻找一个合适的内存块。如果链表中有大小足够的内存块,malloc() 函数就会将其中一个分配给程序,并将其从空闲链表中移除。如果链表中没有足够的内存块,malloc() 函数就会向操作系统请求更多的内存,一般是使用操作系统提供的系统调用(如 brk() 或 mmap())来完成这个操作。

由于 malloc() 函数可能会频繁地向操作系统请求内存,这可能会导致一些性能问题。为了解决这个问题,许多操作系统和 C 库都提供了一些优化技术,如预分配内存池、内存复用等,这些技术可以减少 malloc() 函数的调用次数,提高程序性能。

或者说:
malloc的工作原理如下:

首先,程序通过调用malloc函数向操作系统请求一块指定大小的内存空间。

操作系统会在进程的虚拟地址空间中找到一块足够大的空闲内存,并将其标记为已占用。

操作系统将这块内存的起始地址返回给程序。

malloc函数将返回的地址作为一个指针返回给程序员,程序员可以使用这个指针来访问这块内存。

malloc函数还可能会在返回指针之前,对内存进行一些初始化的操作,例如将内存中的所有位都设置为零。

需要注意的是,malloc分配的内存通常在程序员不再需要它时需要显式地释放,以便操作系统可以重新将其标记为可用空闲内存。否则,程序可能会遭受内存泄漏,导致系统资源浪费并可能导致程序崩溃。

下面是一个使用malloc动态分配内存的简单示例

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

int main() {
    int n, i, sum = 0;
    int *nums;
    printf("请输入整数个数:");
    scanf("%d", &n);
    
    // 动态分配内存空间
    nums = (int*)malloc(n * sizeof(int));
    
    // 读入n个整数,并计算它们的和
    for (i = 0; i < n; i++) {
        printf("请输入第%d个整数:", i + 1);
        scanf("%d", &nums[i]);
        sum += nums[i];
    }
    
    // 输出计算结果
    printf("这%d个整数的和为%d\n", n, sum);
    
    // 释放内存空间
    free(nums);
    nums = NULL;
    return 0;
}

这个程序会提示用户输入整数的个数,然后动态分配一块大小为n个int类型变量的内存空间,读入n个整数,并计算它们的和。最后,程序会释放分配的内存空间,以避免内存泄漏。

需要注意的是,在使用malloc分配内存时,需要对返回的指针进行类型转换,以确保分配的内存大小正确,并且在使用完毕后需要及时调用free函数释放内存空间。

4.free是如何释放内存的,怎么确定释放内存的大小

"free" 是一个 Linux/Unix 系统下的命令,用于查看系统的内存使用情况并释放已经被占用的内存。具体的内存释放过程如下:

  1. 当进程使用 malloc 或者其他动态内存分配函数分配内存时,内存管理器会将对应的内存块标记为已占用状态。
  2. 当进程使用 free 函数释放内存时,内存管理器会将对应的内存块标记为可用状态,但是并不一定会立即返回给操作系统。
  3. 当内存管理器认为可以将一些已经被释放的内存块归还给操作系统时,它会将这些内存块返回给操作系统。

在 Linux/Unix 系统中,使用 free 命令可以查看当前系统的内存使用情况。该命令会列出系统中物理内存和交换空间的总量、已使用量、空闲量等信息。在 free 命令输出的第一行,可以看到一个叫做“free”的值,表示当前系统空闲的物理内存大小。

在程序中,可以使用一些工具来跟踪内存的分配和释放情况,从而确定已经释放的内存大小。例如,在 C/C++ 中,可以使用内存调试工具(如 valgrind)来跟踪内存的分配和释放情况,从而确定已经释放的内存大小。在其他编程语言中,也可以使用类似的工具来进行内存分析和调试。

当一个程序使用 malloc 或其他动态内存分配函数来分配内存时,内存管理器会为该程序保留一块连续的可用内存空间,这块内存空间的大小由程序请求的大小决定。假设程序请求分配了一块大小为 100 字节的内存空间,内存管理器会为该程序保留 100 字节的连续内存空间并将其标记为已占用状态。

当程序使用 free 函数释放该内存空

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇CentOS7-RHCE服务---Web 下一篇linux驱动创建节点文件(device和c..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目