Linux C 编程

内存管理

  1. malloc () 函数

    1
    void *malloc(unsigned int size);

    实例代码

    1
    2
    3
    4
    5
    6
    int main(){
    long *buffer;
    buffer=(long*)malloc(400);
    free(buffer);
    }

  2. calloc () 函数

    1
    void calloc(unsigned n, unsigned size);

    实例代码

    1
    2
    3
    4
    5
    int main(){
    long *buffer;
    buffer=(long*)calloc(20,sizeof(long));
    free(buffer);
    }
  3. realloc () 函数

    1
    void realoc(void *mem_address,unsigned int newsize);

    实例代码

    1
    2
    3
    4
    5
    6
    int main(){
    char *p;
    p=(char*)malloc(100);
    p=realloc(p,256);
    free(p);
    }
  4. memset () 函数

    1
    void memset(void *s,char ch,unsigned n);

    实例代码

    1
    2
    3
    4
    5
    6
    int main(){
    char *p;
    p=(char*)malloc(100);
    memest(s,'\0',strlen(p)-1);
    free(p);
    }

GCC 编译器

GCC 最基本的用法

  • -c ,只编译

  • -o output_filename, 确定输出文件的名称

  • -g 产生符号调试工具

  • -O 对程序进行优化编译、链接。

  • -O2 比 - O 更好的优化编译和链接

进程控制

进程创建

  1. fork () 函数

    1
    pid_t fork(void);

    包含头文件<sys/types.h><unistd.h>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>
    int main(){
    pid_t pid;
    if((pid=fork())<0){
    printf("fork erro\n");
    exit(1);
    }else if(pid==0){
    printf("run in the child process\n");
    }else{
    printf("run in the parent process\n");
    }
    exit(0);

    }

  2. vfork () 函数

    相对于fork()函数,vfork不会负责父进程的资源,父子进程共享地址空间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>

    int main() {
    int shared_variable = 10;
    pid_t pid;

    printf("Before vfork: shared_variable = %d\n", shared_variable);

    pid = vfork();

    if (pid < 0) {
    perror("vfork failed");
    exit(EXIT_FAILURE);
    } else if (pid == 0) {
    // 子进程
    printf("Child process (PID=%d): modifying shared_variable\n", getpid());
    shared_variable = 20; // 直接修改共享内存
    printf("Child process: shared_variable = %d\n", shared_variable);
    exit(EXIT_SUCCESS); // 子进程必须使用_exit或exit退出
    } else {
    // 父进程
    printf("Parent process (PID=%d): resumed execution\n", getpid());
    printf("Parent process: shared_variable = %d\n", shared_variable);
    }

    return 0;
    }

  3. exec () 函数簇

    用一个新的程序替换当前进程映像(即代码段、数据段等),执行新的程序代码,而不创建新进程

    函数名 参数类型简述 查找方式
    execl 列表传参(以 NULL 结尾) PATH 环境变量
    execlp 列表传参(以 NULL 结尾) PATH 环境变量
    execle 列表传参 + 环境变量 PATH 环境变量
    execv 数组传参 PATH 不使用
    execvp 数组传参 PATH 环境变量
    execve 数组传参 + 环境变量 PATH 不使用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <unistd.h>

    int main() {
    execl("/bin/ls", "ls", "-l", "/home", NULL);
    // 如果执行成功,这之后的代码不会被执行
    perror("execl failed");
    return 1;
    }

进程等待

进程等待是指一个进程在某个条件满足之前无法继续执行,必须暂时挂起(阻塞),直到满足特定条件才恢复运行,同步父进程和子进程。

1
2
3
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);

参数说明:

  • status:
    • 类型:int *
    • 用于存储子进程的退出状态。
    • 可以通过宏 WIFEXITED(status)WEXITSTATUS(status) 等宏提取状态信息。

返回值:

  • 成功:返回被收集的子进程的 PID。
  • 失败:返回 -1,并设置 errno
1
2
3
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);

参数说明:

  • pid:
    • 指定等待哪个子进程:
      • pid > 0: 等待特定 PID 的子进程
      • pid == 0: 等待任何和当前进程同组的子进程
      • pid < -1: 等待属于组 ID 为-pid的任意子进程
      • pid == -1: 等待任何子进程(常用)
  • status:
    • 类型:int *
    • 用来获取子进程的状态,与 wait() 类似
  • options:
    • 控制行为的标志位,可组合使用:
      • 0: 默认阻塞等待
      • WNOHANG: 不阻塞等待,如果没有子进程结束则立即返回
      • WUNTRACED: 也返回因信号停止的子进程
      • WCONTINUED: 也返回继续执行的子进程(被 SIGCONT 唤醒)

返回值:

  • 成功:返回结束的子进程 PID
  • 没有结束的子进程(若设置了 WNOHANG):返回 0
  • 错误:返回 -1