[C高手编程] 进程编程与IPC

在这里插入图片描述

💖💖⚡️⚡️专栏:C高手编程-面试宝典/技术手册/高手进阶⚡️⚡️💖💖
「C高手编程」专栏融合了作者十多年的C语言开发经验,汇集了从基础到进阶的关键知识点,是不可多得的知识宝典。如果你是即将毕业的学生,面临C语言的求职面试,本专栏将帮助你扎实地掌握核心概念,轻松应对笔试与面试;如果你已有两三年的工作经验,专栏中的内容将补充你在实践中可能忽略的新技术和技巧;而对于资深的C语言程序员,这里也将是一本实用的技术备查手册,提供全面的知识回顾与更新。无论处在哪个阶段,「C高手编程」都能助你一臂之力,成为C语言领域的行家里手。

概述

本章深入探讨了C语言中的进程编程和进程间通信(IPC)的概念、创建与管理机制,以及不同类型的IPC机制。通过本章的学习,读者将能够理解进程编程的基本原理,并能在实际编程中正确地运用这些概念。

1. 进程的基本概念

1.1 进程定义

进程是程序在一个数据集合上的运行过程,是系统进行资源分配和调度的基本单位。每个进程都有一个唯一的进程标识符(PID)和一个父进程标识符(PPID),除非它是初始进程。

1.2 进程属性

  • 进程ID (PID):标识进程的唯一编号。
  • 父进程ID (PPID):创建该进程的父进程的ID。
  • 进程状态:运行、就绪、等待、终止等。
  • 进程优先级:影响进程调度的顺序。
  • 进程资源使用情况:CPU时间、内存使用等。
  • 进程工作目录:进程当前的工作目录。
  • 环境变量:进程的环境变量列表。
  • 命令行参数:进程启动时传递给它的命令行参数。

1.3 进程控制

  • 创建:使用fork函数创建子进程。
  • 等待:使用waitwaitpid函数等待子进程结束。
  • 终止:使用exit_exit函数终止进程。

在这里插入图片描述

2. 进程控制

2.1 创建进程

2.1.1 fork函数
  • 函数原型pid_t fork(void);
  • 头文件<unistd.h>
  • 参数:无。
  • 返回值:在父进程中返回子进程的PID,在子进程中返回0。如果调用失败,则返回-1。
  • 示例
#include <unistd.h>
#include <stdio.h>int main() {pid_t pid = fork();if (pid < 0) {perror("Fork failed");return 1;} else if (pid == 0) {printf("Child process PID: %d\n", getpid());} else {printf("Parent process PID: %d, Child PID: %d\n", getpid(), pid);}return 0;
}

2.2 终止进程

2.2.1 exit函数
  • 函数原型void exit(int status);
  • 头文件<stdlib.h>
  • 参数:进程退出状态。
  • 示例
#include <stdlib.h>
#include <stdio.h>int main() {printf("Exiting with status 0\n");exit(0);return 0; // This line will never be reached.
}
2.2.2 _exit函数
  • 函数原型void _exit(int status);
  • 头文件<unistd.h>
  • 参数:进程退出状态。
  • 说明_exit函数是直接终止进程而不进行任何清理工作的版本,适用于子进程。
  • 示例
#include <unistd.h>
#include <stdio.h>int main() {printf("Child process exiting\n");_exit(0);return 0; // This line will never be reached.
}

2.3 等待进程

2.3.1 wait函数
  • 函数原型pid_t wait(int *status);
  • 头文件<sys/wait.h>
  • 参数:子进程退出状态。
  • 返回值:子进程的PID,如果没有子进程或出错则返回-1。
  • 示例
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>int main() {pid_t pid = fork();if (pid < 0) {perror("Fork failed");return 1;} else if (pid == 0) { // 子进程printf("Child process exiting\n");_exit(0);} else { // 父进程int status;pid_t wpid = wait(&status);if (wpid == -1) {perror("Wait failed");return 1;}printf("Child process exited with status %d\n", WEXITSTATUS(status));}return 0;
}
2.3.2 waitpid函数
  • 函数原型pid_t waitpid(pid_t pid, int *status, int options);
  • 头文件<sys/wait.h>
  • 参数:特定子进程PID、子进程退出状态、选项。
  • 返回值:子进程的PID,如果没有子进程或出错则返回-1。
  • 示例
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>int main() {pid_t pid = fork();if (pid < 0) {perror("Fork failed");return 1;} else if (pid == 0) { // 子进程printf("Child process exiting\n");_exit(0);} else { // 父进程int status;pid_t wpid = waitpid(pid, &status, 0);if (wpid == -1) {perror("Waitpid failed");return 1;}printf("Child process exited with status %d\n", WEXITSTATUS(status));}return 0;
}

在这里插入图片描述

3. 进程间通信(IPC)

3.1 管道 (Pipes)

3.1.1 简介

管道是一种简单的进程间通信机制,它允许两个进程之间进行单向的数据传输。管道由一对特殊文件描述符组成,一个用于写入数据(写端),另一个用于读取数据(读端)。

3.1.2 函数原型
  • pipe函数
    • 函数原型int pipe(int pipefd[2]);
    • 头文件<unistd.h>
    • 参数:管道描述符数组。
    • 返回值:成功返回0,失败返回-1。
    • 说明:创建一个管道,并返回一个包含两个文件描述符的数组,第一个元素为读端,第二个元素为写端。
3.1.3 示例
#include <unistd.h>
#include <stdio.h>int main() {int pipefd[2];if (pipe(pipefd) == -1) {perror("Pipe creation failed");return 1;}pid_t pid = fork();if (pid < 0) {perror("Fork failed");return 1;} else if (pid == 0) { // 子进程close(pipefd[0]); // 关闭读端char message[] = "Hello, world!";write(pipefd[1], message, strlen(message) + 1);close(pipefd[1]);_exit(0);} else { // 父进程close(pipefd[1]); // 关闭写端char buffer[100];read(pipefd[0], buffer, sizeof(buffer));printf("Received message: %s\n", buffer);close(pipefd[0]);}return 0;
}

3.2 消息队列 (Message Queues)

3.2.1 简介

消息队列是一种更为复杂的IPC机制,允许多个进程通过队列交换数据。消息队列支持多条消息的存储和检索,并且每个消息都可以有自己的类型标签,使得接收者可以根据类型选择性地接收消息。

3.2.2 函数原型
  • msgget函数

    • 函数原型int msgget(key_t key, int flag);
    • 头文件<sys/msg.h>
    • 参数:键值、标志位。
    • 返回值:消息队列标识符,如果出错返回-1。
    • 说明:创建或获取一个消息队列。
  • msgsnd函数

    • 函数原型int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
    • 头文件<sys/msg.h>
    • 参数:消息队列标识符、消息结构体指针、消息长度、标志位。
    • 返回值:成功返回0,失败返回-1。
    • 说明:向消息队列发送一条消息。
  • msgrcv函数

    • 函数原型int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
    • 头文件<sys/msg.h>
    • 参数:消息队列标识符、消息结构体指针、最大接收消息长度、消息类型、标志位。
    • 返回值:成功返回接收的消息长度,失败返回-1。
    • 说明:从消息队列接收一条消息。
  • msgctl函数

    • 函数原型int msgctl(int msqid, int cmd, struct msqid_ds *buf);
    • 头文件<sys/msg.h>
    • 参数:消息队列标识符、命令、缓冲区。
    • 返回值:成功返回0,失败返回-1。
    • 说明:执行各种消息队列控制操作,例如删除消息队列。
3.2.3 示例
#include <sys/msg.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>#define MSGKEY 1234typedef struct {long mtype;char mtext[50];
} my_msg;int main() {key_t key = MSGKEY;int msqid = msgget(key, 0666 | IPC_CREAT);if (msqid == -1) {perror("Message queue creation failed");return 1;}my_msg msg;msg.mtype = 1;strcpy(msg.mtext, "Hello, world!");if (msgsnd(msqid, &msg, sizeof(msg.mtext), 0) == -1) {perror("Message send failed");return 1;}if (msgrcv(msqid, &msg, sizeof(msg.mtext), 1, 0) == -1) {perror("Message receive failed");return 1;}printf("Received message: %s\n", msg.mtext);if (msgctl(msqid, IPC_RMID, NULL) == -1) {perror("Message queue removal failed");return 1;}return 0;
}

3.3 共享内存 (Shared Memory)

3.3.1 简介

共享内存是一种高效的IPC机制,它允许多个进程共享同一块内存区域。这种方式比管道和消息队列更高效,因为它不需要复制数据,而是直接访问同一段物理内存。

3.3.2 函数原型
  • shmget函数

    • 函数原型int shmget(key_t key, size_t size, int shmflg);
    • 头文件<sys/shm.h>
    • 参数:键值、共享内存大小、标志位。
    • 返回值:共享内存标识符,如果出错返回-1。
    • 说明:创建或获取一个共享内存段。
  • shmat函数

    • 函数原型void *shmat(int shmid, const void *shmaddr, int shmflg);
    • 头文件<sys/shm.h>
    • 参数:共享内存标识符、共享内存地址、标志位。
    • 返回值:成功返回指向共享内存的指针,失败返回(void *)-1
    • 说明:将共享内存段映射到进程的地址空间。
  • shmdt函数

    • 函数原型int shmdt(const void *shmaddr);
    • 头文件<sys/shm.h>
    • 参数:指向共享内存的指针。
    • 返回值:成功返回0,失败返回-1。
    • 说明:解除共享内存段的映射。
  • shmctl函数

    • 函数原型int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    • 头文件<sys/shm.h>
    • 参数:共享内存标识符、命令、缓冲区。
    • 返回值:成功返回0,失败返回-1。
    • 说明:执行各种共享内存控制操作,例如删除共享内存段。
3.3.3 示例
#include <sys/shm.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>#define SHMKEY 1234int main() {key_t key = SHMKEY;int shmid = shmget(key, 100, 0666 | IPC_CREAT);if (shmid == -1) {perror("Shared memory creation failed");return 1;}char *shm = shmat(shmid, NULL, 0);if (shm == (char *)-1) {perror("Shared memory attach failed");return 1;}strcpy(shm, "Hello, world!");printf("Data written to shared memory: %s\n", shm);if (shmdt(shm) == -1) {perror("Shared memory detach failed");return 1;}if (shmctl(shmid, IPC_RMID, NULL) == -1) {perror("Shared memory removal failed");return 1;}return 0;
}

3.4 信号量 (Semaphores)

3.4.1 简介

信号量是一种同步原语,用于解决进程间的互斥和同步问题。它可以用来保护共享资源免受并发访问的影响,也可以用来实现进程间的同步。

3.4.2 函数原型
  • semget函数

    • 函数原型int semget(key_t key, int nsems, int semflg);
    • 头文件<sys/sem.h>
    • 参数:键值、信号量集中的信号量数、标志位。
    • 返回值:信号量集标识符,如果出错返回-1。
    • 说明:创建或获取一个信号量集。
  • semop函数

    • 函数原型int semop(int semid, struct sembuf *sops, size_t nsops);
    • 头文件<sys/sem.h>
    • 参数:信号量集标识符、信号量操作数组、操作数。
    • 返回值:成功返回0,失败返回-1。
    • 说明:对信号量集执行操作。
  • semctl函数

    • 函数原型int semctl(int semid, int semnum, int cmd, ...);
    • 头文件<sys/sem.h>
    • 参数:信号量集标识符、信号量索引、命令、额外参数。
    • 返回值:成功返回0或指定值,失败返回-1。
    • 说明:执行各种信号量控制操作,例如设置信号量值。
3.4.3 示例
#include <sys/sem.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>#define SEMKEY 1234union semun {int val;struct semid_ds *buf;unsigned short *array;
};int main() {key_t key = SEMKEY;int semid = semget(key, 1, 0666 | IPC_CREAT);if (semid == -1) {perror("Semaphore creation failed");return 1;}union semun semval;semval.val = 1;if (semctl(semid, 0, SETVAL, semval) == -1) {perror("Semaphore value set failed");return 1;}struct sembuf op;op.sem_num = 0;op.sem_op = -1;op.sem_flg = 0;if (semop(semid, &op, 1) == -1) {perror("Semaphore operation failed");return 1;}op.sem_op = 1;if (semop(semid, &op, 1) == -1) {perror("Semaphore operation failed");return 1;}if (semctl(semid, 0, IPC_RMID, semval) == -1) {perror("Semaphore removal failed");return 1;}return 0;
}

3.5 不同IPC机制的比较

3.5.1 性能
  • 管道:性能较低,因为涉及数据复制。
  • 消息队列:性能中等,比管道稍快,但仍然涉及数据复制。
  • 共享内存:性能最高,因为数据直接在内存中共享,无需复制。
  • 信号量:主要用于同步,性能较高,但不是用于数据传输。
3.5.2 复杂性
  • 管道:相对简单,适用于简单的数据传输。
  • 消息队列:较复杂,支持类型化的消息,适用于复杂的数据交换。
  • 共享内存:最复杂,需要手动管理内存,但提供了高性能的数据交换。
  • 信号量:简单,主要用于同步目的。
3.5.3 可移植性
  • 管道:广泛支持,几乎所有的POSIX系统都支持。
  • 消息队列:POSIX标准的一部分,但并非所有系统都支持。
  • 共享内存:POSIX标准的一部分,但并非所有系统都支持。
  • 信号量:POSIX标准的一部分,但并非所有系统都支持。

3.6 IPC机制的选择

选择合适的IPC机制取决于以下几个因素:

  • 数据传输的需求:如果只需要简单的数据传输,管道可能是最好的选择。
  • 数据的复杂性:如果需要类型化的消息,消息队列是更好的选择。
  • 性能需求:如果对性能有高要求,应考虑使用共享内存。
  • 同步需求:如果主要关注同步,信号量是一个好的选择。
  • 可移植性:如果需要高度可移植的解决方案,管道是最佳选择。

在这里插入图片描述

4. 进程调度

4.1 进程优先级

4.1.1 nice函数
  • 函数原型int nice(int inc);
  • 头文件<unistd.h>
  • 参数:优先级增量。
  • 返回值:当前优先级,失败返回-1。
  • 示例
#include <unistd.h>
#include <stdio.h>int main() {int oldPriority = nice(1);if (oldPriority == -1) {perror("nice failed");return 1;}printf("New priority: %d\n", oldPriority);return 0;
}

4.2 进程调度策略

4.2.1 sched_setscheduler函数
  • 函数原型int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
  • 头文件<sched.h>
  • 参数:进程ID、调度策略、调度参数。
  • 返回值:成功返回0,失败返回-1。
  • 示例
#include <sched.h>
#include <stdio.h>
#include <unistd.h>int main() {struct sched_param param;param.sched_priority = 0; // 默认优先级if (sched_setscheduler(0, SCHED_FIFO, &param) == -1) {perror("Setting scheduler failed");return 1;}printf("Scheduler set to SCHED_FIFO\n");return 0;
}

在这里插入图片描述

5. 进程信号

5.1 信号处理

5.1.1 signal函数
  • 函数原型void signal(int signum, void (*handler)(int));
  • 头文件<signal.h>
  • 参数:信号号、信号处理器。
  • 返回值:无。
  • 示例
#include <signal.h>
#include <stdio.h>
#include <unistd.h>void sigHandler(int sig) {printf("Signal received: %d\n", sig);
}int main() {signal(SIGINT, sigHandler);printf("Press Ctrl+C to send SIGINT\n");while (1) {sleep(1);}return 0;
}

5.2 阻塞信号

5.2.1 sigprocmask函数
  • 函数原型int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
  • 头文件<signal.h>
  • 参数:设置方式、新信号掩码、旧信号掩码。
  • 返回值:成功返回0,失败返回-1。
  • 示例
#include <signal.h>
#include <stdio.h>
#include <unistd.h>int main() {sigset_t mask;sigemptyset(&mask);sigaddset(&mask, SIGINT);if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {perror("Blocking signals failed");return 1;}printf("SIGINT is now blocked\n");sleep(5); // 尝试发送SIGINT,不会被处理return 0;
}

在这里插入图片描述

6. 进程资源限制

6.1 设置资源限制

6.1.1 setrlimit函数
  • 函数原型int setrlimit(int resource, const struct rlimit *rlim);
  • 头文件<sys/resource.h>
  • 参数:资源类型、资源限制。
  • 返回值:成功返回0,失败返回-1。
  • 示例
#include <sys/resource.h>
#include <stdio.h>int main() {struct rlimit rlim;rlim.rlim_cur = 1024; // 当前限制rlim.rlim_max = 1024; // 最大限制if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {perror("Setting resource limit failed");return 1;}printf("Resource limit for RLIMIT_NOFILE set\n");return 0;
}

6.2 获取资源限制

6.2.1 getrlimit函数
  • 函数原型int getrlimit(int resource, struct rlimit *rlim);
  • 头文件<sys/resource.h>
  • 参数:资源类型、资源限制。
  • 返回值:成功返回0,失败返回-1。
  • 示例
#include <sys/resource.h>
#include <stdio.h>int main() {struct rlimit rlim;if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) {perror("Getting resource limit failed");return 1;}printf("Current limit for RLIMIT_NOFILE: %ld\n", rlim.rlim_cur);printf("Maximum limit for RLIMIT_NOFILE: %ld\n", rlim.rlim_max);return 0;
}

结论

本章深入探讨了C语言中的进程编程和进程间通信(IPC)的概念、创建与管理机制,以及不同类型的IPC机制。

进程基本概念

  • 进程定义:进程是程序在一个数据集合上的运行过程,是系统进行资源分配和调度的基本单位。
  • 进程属性:包括进程ID (PID)、父进程ID (PPID)、进程状态、进程优先级等。
  • 进程控制:包括创建(fork)、终止(exit, _exit)和等待(wait, waitpid)进程。

进程控制

  • 创建进程:使用fork函数创建子进程。
  • 终止进程:使用exit_exit函数终止进程。
  • 等待进程:使用waitwaitpid函数等待子进程结束。

进程间通信(IPC)

管道 (Pipes)
  • 简介:管道允许两个进程之间进行单向的数据传输。
  • 函数原型int pipe(int pipefd[2]);
  • 头文件<unistd.h>
  • 参数:管道描述符数组。
  • 返回值:成功返回0,失败返回-1。
消息队列 (Message Queues)
  • 简介:消息队列允许多个进程通过队列交换数据。
  • 函数原型
    • int msgget(key_t key, int flag);
    • int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
    • int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
    • int msgctl(int msqid, int cmd, struct msqid_ds *buf);
  • 头文件<sys/msg.h>
共享内存 (Shared Memory)
  • 简介:共享内存允许多个进程共享同一块内存区域。
  • 函数原型
    • int shmget(key_t key, size_t size, int shmflg);
    • void *shmat(int shmid, const void *shmaddr, int shmflg);
    • int shmdt(const void *shmaddr);
    • int shmctl(int shmid, int cmd, struct shmid_ds *buf);
  • 头文件<sys/shm.h>
信号量 (Semaphores)
  • 简介:信号量用于解决进程间的互斥和同步问题。
  • 函数原型
    • int semget(key_t key, int nsems, int semflg);
    • int semop(int semid, struct sembuf *sops, size_t nsops);
    • int semctl(int semid, int semnum, int cmd, ...);
  • 头文件<sys/sem.h>
IPC机制比较
  • 性能:共享内存性能最高,其次是消息队列,然后是管道。
  • 复杂性:共享内存最复杂,其次是消息队列,管道相对简单。
  • 可移植性:管道最广泛支持,其他机制可能受限于特定系统。
IPC机制选择
  • 数据传输需求:管道适合简单的数据传输。
  • 数据复杂性:消息队列适合类型化的消息交换。
  • 性能需求:共享内存适合高性能的数据交换。
  • 同步需求:信号量适合进程间的同步。
  • 可移植性:管道是最可移植的选择。

进程调度

  • 进程优先级:使用nice函数修改进程的优先级。
  • 进程调度策略:使用sched_setscheduler函数设置进程的调度策略。

进程信号

  • 信号处理:使用signal函数注册信号处理器。
  • 阻塞信号:使用sigprocmask函数阻塞信号。

进程资源限制

  • 设置资源限制:使用setrlimit函数设置资源限制。
  • 获取资源限制:使用getrlimit函数获取资源限制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/56978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SSM+小程序的旅游社交登录管理系统(旅游4)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 ​ 本旅游社交小程序功能有管理员和用户。管理员有个人中心&#xff0c;用户管理&#xff0c;每日签到管理&#xff0c;景点推荐管理&#xff0c;景点分类管理&#xff0c;防疫查询管理&a…

k8s 二进制部署安装(一)

目录 环境准备 初始化操作系统 部署docker 引擎 部署 etcd 集群 准备签发证书环境 部署 Master01 服务器相关组件 apiserver scheduler controller-manager.sh admin etcd 存储了 Kubernetes 集群的所有配置数据和状态信息&#xff0c;包括资源对象、集群配置、元数据…

阿里云镜像源无法访问?使用 DaoCloud 镜像源加速 Docker 下载(Linux 和 Windows 配置指南)

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f343; vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; GitCode&#x1f4ab; Gitee &#x1f…

银河麒麟V10系统下libopenblas.so.0和libllmlmf库的安装

1、当前linux服务器系统是银河麒麟V10&#xff0c;具体的内核和cpu型号如下&#xff1a; 2、使用:uname -a来进行查询 Linux localhost.localdomain 4.19.90-89.16.v2401.ky10.x86_64 #1 SMP Sat Sep 14 13:09:47 CST 2024 x86_64 x86_64 x86_64 GNU/Linux 3、在部署QT开发的应…

高清 MV 无字幕视频素材

在当下的短视频和自媒体时代&#xff0c;高清无字幕的视频素材无疑是创作者们的“得力助手”。不管是用于剪辑情感励志视频、制作搞笑段子&#xff0c;还是创作风景航拍视频&#xff0c;优质的素材库都能让你的创作如虎添翼。今天&#xff0c;我就为大家介绍几个海外的高质量素…

如何使用Qlik Sense Util

Qlik Sense Util 是 Qlik Sense 的一个实用工具&#xff0c;它可以帮助管理员执行各种配置和维护任务。 以下是使用 Qlik Sense Util 工具的一些基本步骤&#xff1a; 1. **运行 QlikSenseUtil.exe**&#xff1a; - 在中心节点上&#xff0c;打开文件资源管理器并导航到 C:…

服务器作业2

架设一台NFS服务器&#xff0c;并按照以下要求配置 关闭防火墙 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 配置文件设置&#xff1a; [rootlocalhost ~]# vim /etc/exports 1、开放/nfs/shared目录&#xff0c;供所有用户查询资料 共享…

Scott Brinker:Martech App 的未来在中小企业和中端市场

中端市场营销支出增加 Product Hunt网站上每周发布的与营销技术相关的产品数量和TechCrunch网站上发布的新融资公告数量持续增加。最近&#xff0c;很多公司都在借助OpenAI、Azure和AWS的新API&#xff0c;赶上生成式人工智能的浪潮。可以肯定的是&#xff0c;有很多重复的想法…

IDEA集成AI的DevAssist插件使用指南

DevAssit使用背景&#xff0c;这类工具通常旨在帮助开发者提高效率&#xff0c;简化开发流程。这类工具包括但不限于&#xff1a; 代码编辑器插件&#xff1a;提供自动补全、代码提示等功能。 构建工具&#xff1a;帮助自动化构建过程。 调试工具&#xff1a;提供更强大的调试功…

anaconda 创建环境失败 解决指南

anaconda 创建环境失败 解决指南 一、问题描述 我在宿舍有一台电脑。由于我经常泡在实验室&#xff0c;所以那台电脑不是经常用&#xff0c;基本吃灰。昨天晚上突然有在那台电脑上使用Camel-AI部署多智能体协同需求&#xff0c;便戳开了电脑&#xff0c;问题也随之而来。 当…

河北统计年鉴(2000-2021年)

《河北统计年鉴》不仅记录了河北省经济社会发展的历史轨迹&#xff0c;还系统地展示了其现状。它涵盖了经济发展、人口就业、社会事业、居民生活、环境保护等多个领域的数据资料 2000-2021年河北统计年鉴数据整理资源-CSDN文库https://download.csdn.net/download/2401_845856…

创建和管理IPAM

IPAM&#xff08;IP Address Manager&#xff09;为用户提供全局地址管理的能力。创建IPAM后&#xff0c;您可以在IPAM中创建私网作用范围。每个私网作用范围都代表一个独立的地址作用域&#xff0c;在私网作用范围中可以创建地址池来管理和分配IP地址资源。本文为您介绍如何创…

esp32学习:语音识别教程esp-skainet库的使用

乐鑫推出了基于esp_sr算法的语音识别应用esp-skainet。官方介绍&#xff1a;ESP-Skainet 以最便捷的方式支持基于乐鑫的 ESP32系列 芯片的唤醒词识别和命令词识别应用程序的开发。使用 ESP-Skainet&#xff0c;您可以轻松构建唤醒词识别和命令词识别应用程序。 支持的主要功能…

模拟信号采集显示器+GPS同步信号发生器制作全过程(焊接、问题、代码、电路)

1、制作最小系统板 在制作最小系统板的时候&#xff0c;要用USB转TTL给板子供电&#xff0c;留了一个电源输入的四个接口&#xff0c;同时又用排针引出来VCC和GND用于后续其他外设的电源供应&#xff0c;电源配有电源指示灯和保护电容&#xff0c; 当时在焊接的时候把接口处的…

首席数据官和首席数据分析官

根据分析人士的预测&#xff0c;首席数据官&#xff08;CDO&#xff09;和首席数据分析官&#xff08;CDAO&#xff09;必须更有效地展示他们对企业和AI项目的价值&#xff0c;以保障其在高管层的地位。Gartner的最新报告指出&#xff0c;CDO和CDAO在AI时代需要重新塑造自身定位…

Python毕业设计选题:基于Django+Vue的图书馆管理系统

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 系统首页 图书馆界面 图书信息界面 个人中心界面 后台登录界面 管理员功能界面 用户…

Docker:namespace环境隔离 CGroup资源控制

Docker&#xff1a;namespace环境隔离 & CGroup资源控制 Docker虚拟机容器 namespace相关命令ddmkfsdfmountunshare 进程隔离文件隔离 CGroup相关命令pidstatstresscgroup控制 内存控制CPU控制 Docker 在开发中&#xff0c;经常会遇到环境问题&#xff0c;比如程序依赖某个…

RabbitMq-队列交换机绑定关系优化为枚举注册

&#x1f4da;目录 &#x1f4da;简介:&#x1f680;比较&#x1f4a8;通常注册&#x1f308;优化后注册 ✍️代码&#x1f4ab;自动注册的关键代码 &#x1f4da;简介: 该项目介绍&#xff0c;rabbitMq消息中间件&#xff0c;对队列的注册&#xff0c;交换机的注册&#xff0c…

D50【python 接口自动化学习】- python基础之类

day50 init方法 学习日期&#xff1a;20241027 学习目标&#xff1a;类 -- 64 init方法&#xff1a;如何为对象传递参数&#xff1f; 学习笔记&#xff1a; 魔术方法 init方法 class Klass(object):# 定义初始化方法&#xff0c;类实例化时自动进行初始化def __init__(self…

检索引擎Elasticsearch

一.为什么要用Elasticsearch 由于我们在运行我们的项目的时候通常都是将数据存到mysql或者sql serve等数据库中&#xff0c;在进行数据搜索时使用sql 语句 like进行模糊匹配查询&#xff0c;其一&#xff1a;虽然可以查到数据&#xff0c;但是它模糊匹配查询速度较慢&#xff0…