Linux进程详解

发布时间:2023-05-22

一、进程基本概念

进程是指正在执行中的程序,并且具有独立运行的能力,是操作系统分配资源和时间的基本单位。进程包括进程控制块和执行代码两部分。 每个进程都有唯一的进程号(PID),并且可以通过shell命令ps来查看系统中运行的所有进程及其状态。

二、进程间通信(IPC)

在Linux中,进程间通信(IPC)是非常重要的。常见的IPC方式有:管道、信号、共享内存、消息队列等。 共享内存是较高效的进程间通信方式之一,可以允许多个进程在同一段物理内存中进行读写操作。下面是获取共享内存并进行操作的示例代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <unistd.h>
    #define SHMSZ 27
    int main() {
        char c;
        int shmid;
        key_t key = 5678;
        char *shm, *s;
        if((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
            perror("shmget");
            exit(1);
        }
        if((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
            perror("shmat");
            exit(1);
        }
        s = shm;
        for(c = 'a'; c <= 'z'; c++){
            *s++ = c;
        }
        *s = '\0';
        while(*shm != '*') {
            sleep(1);
        }
        exit(0);
    }

三、进程调度

进程调度是指操作系统根据一定的算法从就绪队列中选择下一个进程,对其进行CPU分配,从而实现多个进程并发执行的过程。 Linux内核采用了抢占式调度和时间片轮转调度算法。常用的调度算法有:先来先服务、最短作业优先、优先级调度、时间片轮转调度等。 下面是进行进程优先级调度的示例代码:

    #include <linux/sched.h>
    #include <linux/kernel.h>
    #include <linux/module.h>
    static int __init my_init(void) {
        printk(KERN_INFO "Hello, world!\n");
        struct task_struct * p;
        for_each_process(p) { //遍历所有进程
            printk(KERN_INFO "name: %s, state: %ld, pid: %d\n", p->comm, p->state, p->pid);
        }
        return 0;
    }
    static void __exit my_exit(void) {
        printk(KERN_INFO "Bye, world!\n");
    }
    module_init(my_init);
    module_exit(my_exit);
    MODULE_LICENSE("GPL");

四、进程状态转换

在Linux中,进程状态可以分为就绪态、运行态、挂起态等几种状态。进程状态的转换涉及到进程阻塞、挂起、唤醒等操作。 下面是进程状态转换的示例代码:

    #include <stdio.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <unistd.h>
    int main() {
        int count;
        pid_t pid;
        if ((pid = fork()) == -1) {
            perror("fork");
            exit(1);
        }
        if (pid == 0) {
            for (count = 0; count < 10; count++) {
                printf("Child: %d\n", count);
                sleep(1);
            }
            exit(0);
        } else {
            sleep(5);
            kill(pid, SIGSTOP); //挂起子进程
            printf("Parent has stopped child!\n");
            sleep(5);
            kill(pid, SIGCONT); //恢复子进程
            printf("Parent has resumed child!\n");
            for (count = 0; count < 10; count++) {
                printf("Parent: %d\n", count);
                sleep(1);
            }
        }
        exit(0);
    }

五、多线程

在Linux中,一个进程可以包含多个线程,每个线程都可以独立地运行和执行任务。线程可以大大提高程序的并发性,提高程序的效率。 下面是创建线程的示例代码:

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    void *thread_function(void *arg){
        printf("Thread function is running. Argument was %s\n", (char *) arg);
        sleep(3); //睡眠3秒
        printf("Thread function is done.\n");
        return NULL;
    }
    int main() {
        int res;
        pthread_t a_thread;
        void *thread_result;
        res = pthread_create(&a_thread, NULL, thread_function, "Hello world!");
        if (res != 0) {
            perror("Thread creation failed");
            exit(EXIT_FAILURE);
        }
        printf("Waiting for thread to finish...\n");
        res = pthread_join(a_thread, &thread_result);
        if (res != 0) {
            perror("Thread join failed");
            exit(EXIT_FAILURE);
        }
        printf("Thread joined, it returned %s\n", (char *) thread_result);
        printf("Main function is done.\n");
        exit(EXIT_SUCCESS);
    }