Linux c/c++之IPC进程间通信

简介: 这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。

1. IPC定义

IPC技术: 内核进程通信(Inter Process Communication)

2. 共享内存

2.1 共享内存定义

    shm(share memory),在主机上指定一块内存作为进程之间的共享内存, 不同的进程之间可以通过一些方式去访问这块内存。

2.2 shm(共享内存 编程模型)

  1. 创建key ftok函数
  2. 创建共享内存 shmget函数
  3. 挂载共享内存 shmat函数
  4. 卸载共享内存 shmdt函数
  5. 删除共享内存 shmctl函数

2.3 shm的一些函数原型

2.3.1 ftok函数

//头文件
#include <sys/types.h>
#include <sys/ipc.h>
//函数原型
key_t ftok(const char *pathname, int proj_id);

//返回值: 返回值为一个4byte的整数(返回-1失败)
//0--15  bit: pathname的st_ino属性的低16位
//16--23 bit: pathname的st_dev属性的低8位
//24--31 bit: pro_id的低8位

//参数一: 传入一个路径,一般使用当前路径"."
//参数二: 任意的一个整数,因为要做进程间通信,
//那么另一个进程需要与这个数保持一致才能找到对应的ipcid,一般只使用8个bit,因此取值范围在0--255

2.3.2 shmget函数

//头文件
#include <sys/ipc.h>
#include <sys/shm.h>
//函数原型
int shmget(key_t key, size_t size, int shmflg);

//返回值: 返回一个整数(返回-1失败) 

//参数一: ftok函数的返回值
//参数二: 共享的内存大小(byte)(如果数值为1 -- 4096,实际申请4k(一页))
//参数三: 主要与一些标志有关
// IPC_CREAT  不存在共享内存就创建,否则打开
// IPC_EXCL   不存在共享内存才创建,否则错误

2.3.3 shmat函数

//头文件
#include <sys/types.h>
#include <sys/shm.h>
//函数原型
void *shmat(int shmid, const void *shmaddr, int shmflg);

//返回值: 返回申请的共享内存的首地址(返回-1则挂载失败)

//参数一: shmget函数的返回值
//参数二: 一般为0,表示连接到一个由内核选择的可用地址之上
//参数三: 一般为0

2.3.4 shmdt函数

//头文件
#include <sys/types.h>
#include <sys/shm.h>
//函数原型
int shmdt(const void *shmaddr);

//返回值: 成功返回0,失败返回-1
//参数一: shmat函数的返回值

2.3.5 shmctl函数

//头文件
#include <sys/ipc.h>
#include <sys/shm.h>
//函数原型
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

//返回值: 失败返回-1,
//参数一: shmget函数的返回值
//参数二: 设置调用者对共享内存段的权限
// IPC_STAT: 调用者必须对共享内存具有读权限
// IPC_SET: 对shmid_ds 中的某些值做一些修改
// IPC_RMID: 表示销毁某个段
// IPC_INFO: 返回共享内存限制和参数的信息
// SHM_INFO: 返回一个shm_info的结构体
// SHM_STAT: 返回该内存段在内核数组的索引,该数组记录所有共享内存段的信息
// SHM_LOCK: 防止交换共享内存段
// SHM_UNLOCK: 解除防止交换共享内存段
//参数三: 一个指向shmid_ds的结构体指针
struct shmid_ds 
{   struct ipc_perm shm_perm;/*用户权限*/
    size_t shm_segsz;/* segment (bytes)的大小*/
    time_t shm_atime;/*最后连接时间*/
    time_t shm_dtime;/*最后的分离时间时间*/
    time_t ctime;/*上次更改时间*/
    pid_t  shm_cpid;/*创建器的PID*/
    ......
};

2.4 共享内存的优势与缺点

2.4.1 优势

因为两个进程可以使用一段内存, 这就构成了进程之间的双向通信, 无疑传输速率是很快的, 是最快的进程间通信方式。因为不同的进程之间是直接从这一段内存之中存放、读取数据。而且使用共享内存进行通信对数据是没有什么限制的。并且共享内存的生命周期与系统内核的生命周期是一致的。

2.4.2 缺点

共享内存并没有提供同步机制,在一个进程对共享内存进行写操作结束之前,另一个进程是不能对这块共享内存进行同步访问的,因为我们通常想要实现的是多个进程对共享内存的同步访问。

2.5 共享内存示例

使用shmA.c从共享内存中读取数据, shmB.c向共享内存中写入数据, shmctl.c删除共享内存段

2.5.1 共享内存数据读取端

//shmA.c  读取端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>

int* p = NULL;
void hand(){
    //5.卸载功能共享内存
    shmdt(p);
    printf("bye bye!\n");

    exit(0);
}
int main(){
    signal(SIGINT,hand);
    //1.创建key
    key_t key = ftok(".",'m');  //参数二在256之内
    if(-1 == key) printf("create key error:%m\n"),exit(-1);
    printf("create key success!\n");
    //2.创建共享内存   内存单位之页   1页 == 4k
    int shmid = shmget(key,4096,IPC_CREAT);
    if(-1 == shmid) printf("shmget error:%m\n"),exit(-1);
    printf("shmget success!\n");
    //3.挂载共享内存
    p = (int*)shmat(shmid,NULL,0);
    if((int*)-1 == p) printf("shmat error:%m\n"),exit(-1);
    printf("shmat success!\n");
    //4.使用共享内存
    while(1){
        printf("%d\n",*p);
        sleep(1);
    }

    return 0;
}

2.5.2 共享内存数据发送端

//shmB.c  写入端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>

int* p = NULL;
void hand(){
    //5.卸载功能共享内存
    shmdt(p);
    printf("bye bye!\n");

    exit(0);
}
int main(){
    signal(SIGINT,hand);
    //1.创建key
    key_t key = ftok(".",'m');  //参数二在256之内
    if(-1 == key) printf("create key error:%m\n"),exit(-1);
    printf("create key success!\n");
    //2.获取共享内存  
    int shmid = shmget(key,4096,IPC_CREAT);
    if(-1 == shmid) printf("shmget error:%m\n"),exit(-1);
    printf("shmget success!\n");
    //3.挂载共享内存
    p = (int*)shmat(shmid,NULL,0);
    if(NULL == p) printf("shmat error:%m\n"),exit(-1);
    printf("shmat success!\n");
    //4.使用共享内存
    int n = 0;
    while(1){
        *p = n++;
        sleep(1);
    }

    return 0;
}

2.5.3 共享内存段删除端

//shmctl.c  删除共享内存
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main(){
    //1.创建key
    key_t key = ftok(".",'m');  //参数二在256之内
    if(-1 == key) printf("create key error:%m\n"),exit(-1);
    printf("create key success!\n");
    //2.获取共享内存  
    int shmid = shmget(key,4096,IPC_CREAT);
    if(-1 == shmid) printf("shmget error:%m\n"),exit(-1);
    printf("shmget success!\n");

    //3.删除共享内存
    shmctl(shmid,IPC_RMID,NULL);

    return 0;
}

2.5.4 运行结果

shmA读取数据进程端单独运行:

shmA读取数据进程端与shmB写入数据进程端同时运行:

ipcs -m 命令查看当前共享内存信息:

使用shmctl删除当前创建的共享内存段后:

3. 消息队列

3.1 消息队列定义

    msg(message queue), 在主机上指定一个或者多个队列, 一方进程向队列之中放数据, 另一方从队列之中拿东西。

3.2 msg(消息队列 编程模型)

  1. 创建key ftok函数
  2. 创建消息队列 msgget函数
  3. 收发消息 msgrcv 函数 msgsnd 函数
  4. 删除消息队列 msgctl函数

3.3 msg的一些函数原型

3.3.1 ftok函数

//头文件
#include <sys/types.h>
#include <sys/ipc.h>
//函数原型
key_t ftok(const char *pathname, int proj_id);

//返回值: 返回值为一个4byte的整数(返回-1失败)
//0--15  bit: pathname的st_ino属性的低16位
//16--23 bit: pathname的st_dev属性的低8位
//24--31 bit: pro_id的低8位

//参数一: 传入一个路径,一般使用当前路径"."
//参数二: 任意的一个整数,因为要做进程间通信,
//那么另一个进程需要与这个数保持一致才能找到对应的ipcid,一般只使用8个bit,因此取值范围在0--255

3.3.2 msgget函数

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);

//返回值: 返回一个整数(-1表示失败)
//参数一: ftok函数的返回值
//参数二: 主要是一些标志
// IPC_CREAT  不存在共享内存就创建,否则打开
// IPC_EXCL   不存在共享内存才创建,否则错误

3.3.3 msgrcv函数

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

//返回值: (失败返回-1)返回实际复制到mtext数组中的字节数
//参数一: msgget函数的返回值
//参数二: 指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构
    struct msgbuf {
        long mtype;    
        char mtext[1];  //可以是1,也可以是其它数
    };
//参数三: 消息的大小
//参数四: 从消息队列内读取的消息形态。如果值为零,则表示消息队列中的所有消息都会被读取。
//参数五: 用来指明核心程序在队列没有数据的情况下所应采取的行动。如果msgflg和常数IPC_NOWAIT合用,则在消息队列呈空时,不做等待马上返回-1,并设定错误码为ENOMSG。

3.3.4 msgsnd函数

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

//返回值: (失败返回-1)成功返回0
//参数一: msgget函数的返回值
//参数二: 指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构
    struct msgbuf {
        long mtype;    
        char mtext[1];  //可以是1,也可以是其它数
    };
//参数三: 消息的大小
//参数四: 用来指明核心程序在队列没有数据的情况下所应采取的行动。如果msgflg和常数IPC_NOWAIT合用,则在msgsnd()执行时若是消息队列已满,则msgsnd()将不会阻塞,而会立即返回-1。当msgflg为0时,msgsnd()及msgrcv()在队列呈满或呈空的情形时,采取阻塞等待的处理模式。

3.3.5 msgctl函数

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

//返回值: 失败返回-1,
//参数一: shmget函数的返回值
//参数二: 设置调用者对共享内存段的权限
// IPC_STAT: 调用者必须对共享内存具有读权限
// IPC_SET: 对msqid_ds 中的某些值做一些修改
// IPC_RMID: 表示销毁某个段
// IPC_INFO: 返回共享内存限制和参数的信息
// MSG_INFO: 返回一个msginfo的结构体
// MSG_STAT: 返回该内存段在内核数组的索引,该数组记录所有共享内存段的信息
//参数三: 一个指向msqid_ds 的结构体指针
struct msqid_ds {
               struct ipc_perm msg_perm;     /* 所有权和权限 */
               time_t          msg_stime;    /* 最后一次 msgsnd(2) */
               time_t          msg_rtime;    /* 最后一次 msgrcv(2) */
               time_t          msg_ctime;    /* 最后一次修改的时间*/
               unsigned long   __msg_cbytes; /* 当前队列的字节数(非标准) */
               msgqnum_t       msg_qnum;     /* 当前队列中的消息数 */
               msglen_t        msg_qbytes;   /* 队列允许的最大字节数 */
               pid_t           msg_lspid;    /* 上一次 msgsnd(2) 的PID*/
               pid_t           msg_lrpid;    /* PID of last msgrcv(2) */
           };

3.4 消息队列的优势与缺点

3.4.1 优势

消息队列提供了一种从进程向另一个进程发送一个数据块的方法。每个数据块都被认为是一个类型,接收进程接收的数据块可以有不同的类型值。可以通过发送消息来避免命名管道的同步和阻塞的问题。消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的,且消息队列的读取不一定是先入先出。

3.4.2 缺点

每个数据块有大小限制, 整个操作系统中所有的数据块总大小也有一个限制。

3.5 消息队列演示

3.5.1 消息发送端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

//发送端进程
struct msgbuf{
    long type;
    char buff[20];
};
int main(){
    struct msgbuf msg;
    //1.创建key
    key_t key = ftok(".",'q');
    if(-1 == key) printf("ftok error:%m\n"),exit(-1);
    printf("ftok success!\n");
    //2. 创建消息队列
    int msgid = msgget(key,IPC_CREAT | 0666);
    if(-1 == msgid) printf("msgget error:%m\n"),exit(-1);
    printf("msgget success!\n");
    //3. 发消息
    int r;
    while(1){
        printf("请输入消息类型:");
        scanf("%ld",&msg.type);
        printf("请输入消息内容:");
        scanf("%s",msg.buff);
        r = msgsnd(msgid,&msg,sizeof(msg),IPC_NOWAIT); //IPC_NOWAIT非阻塞方式
        printf("r: %d\n",r);
    }


    return 0;
}

3.5.2 消息接收端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

#define TYPE 2
//接收端进程
struct msgbuf{
    long type;
    char buff[20];
};
int main(){
    struct msgbuf msg;
    msg.type = TYPE;
    //1.创建key
    key_t key = ftok(".",'q');
    if(-1 == key) printf("ftok error:%m\n"),exit(-1);
    printf("ftok success!\n");
    //2. 创建消息队列
    int msgid = msgget(key,IPC_CREAT | 0666);
    if(-1 == msgid) printf("msgget error:%m\n"),exit(-1);
    printf("msgget success!\n");
    //3. 接收消息
    int r;
    while(1){
        memset(msg.buff,0,20);
        r = msgrcv(msgid,&msg,sizeof(msg),TYPE,IPC_NOWAIT);
        printf("r:%d msg:%s type:%ld\n", r, msg.buff, msg.type);
        sleep(1);
    }
    return 0;
}

3.5.3 消息队列删除端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

int main(){
    //1.创建key
    key_t key = ftok(".",'q');
    if(-1 == key) printf("ftok error:%m\n"),exit(-1);
    printf("ftok success!\n");
    //2. 创建消息队列
    int msgid = msgget(key,IPC_CREAT | 0666);
    if(-1 == msgid) printf("msgget error:%m\n"),exit(-1);
    printf("msgget success!\n");
    //3. 删除当前消息队列
    msgctl(msgid,IPC_RMID,NULL);


    return 0;
}

3.5.6 运行结果

当发送端的消息类型是type = 2 时, 接收端将消息队列中 type为2的消息取出来处理, type为3的消息仍然在消息队列中

使用命令查看创建的消息队列 (已用字节数是刚刚的type为3的消息)

继续发送一个type为5的消息和一个type为6的消息,发现已用字节数变成了96

删除消息队列后

4. 旗语(信号量)

4.1 旗语(信号量定义)

sem(semaphore), 让多个进程不可能同时访问一块区域

4.2 sem(信号量 编程模型)

  1. 创建key ftok函数
  2. 创建旗语(信号量) semget函数
  3. 初始化旗语(信号量) semctl函数
  4. 使用旗语(信号量) semop函数
  5. 删除旗语(信号量) semctl函数

4.3 sem的一些函数原型

4.3.1 ftok函数

//头文件
#include <sys/types.h>
#include <sys/ipc.h>
//函数原型
key_t ftok(const char *pathname, int proj_id);

//返回值: 返回值为一个4byte的整数(返回-1失败)
//0--15  bit: pathname的st_ino属性的低16位
//16--23 bit: pathname的st_dev属性的低8位
//24--31 bit: pro_id的低8位

//参数一: 传入一个路径,一般使用当前路径"."
//参数二: 任意的一个整数,因为要做进程间通信,
//那么另一个进程需要与这个数保持一致才能找到对应的ipcid,一般只使用8个bit,因此取值范围在0--255

4.3.2 semget函数

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semget(key_t key, int nsems, int semflg);

//返回值: 返回一个整数(-1表示失败)
//参数一: ftok函数返回值
//参数二: 创建信号量的个数(一般创建一个)
//参数三: 主要是一些标志
// IPC_CREAT  不存在共享内存就创建,否则打开
// IPC_EXCL   不存在共享内存才创建,否则错误

4.3.3 semop函数

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semop(int semid, struct sembuf *sops, size_t nsops);

//返回值: 成功返回0, 失败返回-1
//参数一: semget函数返回值()
//参数二: 信号量的一些信息(用户可更改)
sops[0].sem_num = 0; 信号量的索引
sops[0].sem_op = 0;  加还是减以及加减的值
sops[0].sem_flg = 0; 一般设置为0
//参数三: 操作的次数

4.3.4 semctl函数

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semctl(int semid, int semnum, int cmd, ...);

//返回值: 失败返回-1
//参数一: semget函数返回值(信号量的标识id)
//参数二: 信号量的标识,标识使用第几个信号量(从0开始)
//参数三: 一个指向msqid_ds 的结构体指针
// IPC_STAT: 调用者必须对共享内存具有读权限
// IPC_SET: 对semid_ds 中的某些值做一些修改
// IPC_RMID: 表示销毁某个段
// IPC_INFO: 返回共享内存限制和参数的信息
// SEM_INFO: 返回一个seminfo的结构体
// SEM_STAT: 返回该内存段在内核数组的索引,该数组记录所有共享内存段的信息
// GETALL:   获取集合中所有的信号量
// GETNCNT:  返回集合中指定semnum的信号量
// GETPID:   返回指定semnum的sempid的值
// GETVAL:   返回指定semnum的semval的值
// GETZCNT:  返回集合中第一个信号量的semzcnt值
// SETALL:   为集合中所有信号量设置值
// SETVAL:   设置一个信号量的值
//参数四: 缺省参数, union semun类型的指针
 union semun {
               int              val;    /* SETVAL */
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */
               struct seminfo  *__buf;  /* Buffer for IPC_INFO*/
           };

4.4 旗语(信号量)的优势与缺点

4.4.1 优势

节省了打开文件以及关闭文件的时间,数据传输速率提高

4.4.2 缺点

一但被锁定, 在解锁之前出现程序崩溃等问题, 就会导致锁定的信号量无法恢复, 形成永久性的占用, 使用文件操作的方式则不会出现这种情况, 因为在进程退出的时候, 文件就会被关闭, 在该文件描述符上的锁定就会被自动解除。

4.5 旗语(信号量演示)

4.5.1 信号量加端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int main(){
    //1. 创建key
    key_t key = ftok(".",'s');
    if(-1 == key) printf("ftok error:%m\n"),exit(-1);
    printf("ftok success!\n");
    //2. 创建信号量
    int semid = semget(key,1,IPC_CREAT | 0654);
    if(-1 == semid) printf("semget error:%m\n"),exit(-1);
    printf("semget success!\n");

    //3. 使用旗语
    struct sembuf buf;
    buf.sem_num = 0;
    buf.sem_op = 1;     //加
    buf.sem_flg = 0;

    while(1){
        semop(semid,&buf,1); //操作一次
        sleep(1);
    }


    return 0;
}

4.5.2 信号量减端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

union semun{
    int val;
    struct semid_ds* buf;
    unsigned short* array;
    struct seminfo* __buf;
};
int main(){
    //1. 创建key
    key_t key = ftok(".",'s');
    if(-1 == key) printf("ftok error:%m\n"),exit(-1);
    printf("ftok success!\n");
    //2. 创建信号量
    int semid = semget(key,1,IPC_CREAT | 0654);
    if(-1 == semid) printf("semget error:%m\n"),exit(-1);
    printf("semget success!\n");
    //3. 初始化信号量
    union semun u;
    u.val = 5;
    semctl(semid,0,SETVAL,u);
    //4. 使用旗语
    struct sembuf buf;
    buf.sem_num = 0;
    buf.sem_op = -1;    //减
    buf.sem_flg = 0;

    int n = 0;
    while(1){
        printf("卖出%d辆!\n",++n);
        semop(semid,&buf,1); //操作一次
    }

    return 0;
}

4.5.3 信号量删除

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>

int main(){
    //1. 创建key
    key_t key = ftok(".",'s');
    if(-1 == key) printf("ftok error:%m\n"),exit(-1);
    printf("ftok success!\n");
    //2. 创建信号量
    int semid = semget(key,1,IPC_CREAT | 0654);
    if(-1 == semid) printf("semget error:%m\n"),exit(-1);
    printf("semget success!\n");

    //3. 删除旗语
    semctl(semid,0,IPC_RMID,NULL);

    return 0;
}

4.5.4 运行结果

设置信号量 0 初始值为5, 运行A后,再运行B:

ipcs -s 查看信号量信息:

删除创建的信号量后,ipcs -s 查看信号量信息:

5. 管理IPC的ipc命令簇

5.1 ipcs 查看命令

  1. -m 查看shm(共享内存)
  2. -q 查看msg(消息队列)
  3. -s 查看sem(信号量)

5.2 ipcrm 删除命令

  1. -m 删除shm(共享内存)
  2. -q 删除msg(消息队列)
  3. -s 删除sem(信号量)

注: shm msg sem 都必须先有一个key(key是根据fd来创建的)

相关文章
|
15天前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
46 4
linux进程管理万字详解!!!
|
5天前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
41 8
|
14天前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
47 4
|
15天前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
16天前
|
消息中间件 存储 Linux
|
23天前
|
运维 Linux
Linux查找占用的端口,并杀死进程的简单方法
通过上述步骤和命令,您能够迅速识别并根据实际情况管理Linux系统中占用特定端口的进程。为了获得更全面的服务器管理技巧和解决方案,提供了丰富的资源和专业服务,是您提升运维技能的理想选择。
25 1
|
5月前
|
监控 Linux 应用服务中间件
探索Linux中的`ps`命令:进程监控与分析的利器
探索Linux中的`ps`命令:进程监控与分析的利器
126 13
|
4月前
|
运维 关系型数据库 MySQL
掌握taskset:优化你的Linux进程,提升系统性能
在多核处理器成为现代计算标准的今天,运维人员和性能调优人员面临着如何有效利用这些处理能力的挑战。优化进程运行的位置不仅可以提高性能,还能更好地管理和分配系统资源。 其中,taskset命令是一个强大的工具,它允许管理员将进程绑定到特定的CPU核心,减少上下文切换的开销,从而提升整体效率。
掌握taskset:优化你的Linux进程,提升系统性能
|
4月前
|
弹性计算 Linux 区块链
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
167 4
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
|
3月前
|
算法 Linux 调度
探索进程调度:Linux内核中的完全公平调度器
【8月更文挑战第2天】在操作系统的心脏——内核中,进程调度算法扮演着至关重要的角色。本文将深入探讨Linux内核中的完全公平调度器(Completely Fair Scheduler, CFS),一个旨在提供公平时间分配给所有进程的调度器。我们将通过代码示例,理解CFS如何管理运行队列、选择下一个运行进程以及如何对实时负载进行响应。文章将揭示CFS的设计哲学,并展示其如何在现代多任务计算环境中实现高效的资源分配。