欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > Linux:进程间通信

Linux:进程间通信

2025/6/22 9:01:16 来源:https://blog.csdn.net/hie98894/article/details/148767408  浏览:    关键词:Linux:进程间通信

在Linux系统中,进程间通信(IPC, Inter-Process Communication)是指多个进程之间的数据交换和同步手段。常见的IPC机制包括共享内存、消息队列和信号量。本文将详细讲解这三种IPC机制,并提供小项目示例和相关指令。

一、共享内存

共享内存是最快的IPC机制,因为它允许多个进程直接访问同一块内存区域。共享内存的使用涉及几个系统调用:shmgetshmatshmdt和 shmctl

1.1 创建和附加共享内存

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define SHM_SIZE 1024  // 共享内存大小int main() {key_t key = ftok("shmfile", 65);  // 生成唯一键值int shmid = shmget(key, SHM_SIZE, 0666|IPC_CREAT);  // 创建共享内存char *str = (char*) shmat(shmid, (void*)0, 0);  // 连接共享内存printf("Write Data: ");fgets(str, SHM_SIZE, stdin);printf("Data written in memory: %s\n", str);shmdt(str);  // 分离共享内存return 0;
}
​

1.2 读取共享内存

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>#define SHM_SIZE 1024  // 共享内存大小int main() {key_t key = ftok("shmfile", 65);  // 生成唯一键值int shmid = shmget(key, SHM_SIZE, 0666|IPC_CREAT);  // 获取共享内存IDchar *str = (char*) shmat(shmid, (void*)0, 0);  // 连接共享内存printf("Data read from memory: %s\n", str);shmdt(str);  // 分离共享内存shmctl(shmid, IPC_RMID, NULL);  // 销毁共享内存return 0;
}
​

1.3 相关指令

  • ipcs:显示当前系统的IPC设施状态。
  • ipcrm:删除指定的IPC对象。

二、消息队列

消息队列允许进程以消息的形式进行通信,每个消息都有一个类型标识符。消息队列的相关系统调用包括 msggetmsgsndmsgrcv和 msgctl

2.1 发送消息

#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct mesg_buffer {long mesg_type;char mesg_text[100];
} message;int main() {key_t key = ftok("msgfile", 65);  // 生成唯一键值int msgid = msgget(key, 0666 | IPC_CREAT);  // 创建消息队列message.mesg_type = 1;printf("Write Data: ");fgets(message.mesg_text, 100, stdin);msgsnd(msgid, &message, sizeof(message), 0);  // 发送消息printf("Data send is : %s\n", message.mesg_text);return 0;
}
​

2.2 接收消息

#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct mesg_buffer {long mesg_type;char mesg_text[100];
} message;int main() {key_t key = ftok("msgfile", 65);  // 生成唯一键值int msgid = msgget(key, 0666 | IPC_CREAT);  // 获取消息队列IDmsgrcv(msgid, &message, sizeof(message), 1, 0);  // 接收消息printf("Data Received is : %s\n", message.mesg_text);msgctl(msgid, IPC_RMID, NULL);  // 销毁消息队列return 0;
}
​

2.3 相关指令

  • ipcs -q:显示当前系统的消息队列。
  • ipcrm -q <msgid>:删除指定的消息队列。

三、信号量

信号量是用于进程同步的IPC机制。信号量的相关系统调用包括 semgetsemop和 semctl

3.1 创建和初始化信号量

#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>union semun {int val;struct semid_ds *buf;unsigned short *array;
};int main() {key_t key = ftok("semfile", 65);  // 生成唯一键值int semid = semget(key, 1, 0666 | IPC_CREAT);  // 创建信号量集union semun sem_union;sem_union.val = 1;semctl(semid, 0, SETVAL, sem_union);  // 初始化信号量return 0;
}
​

3.2 P操作和V操作

#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>void sem_op(int semid, int op) {struct sembuf sb;sb.sem_num = 0;sb.sem_op = op;sb.sem_flg = 0;semop(semid, &sb, 1);
}int main() {key_t key = ftok("semfile", 65);  // 生成唯一键值int semid = semget(key, 1, 0666);  // 获取信号量IDprintf("Waiting for semaphore...\n");sem_op(semid, -1);  // P操作printf("Enter critical section...\n");// 进入临界区sleep(5);  // 模拟临界区操作printf("Leaving critical section...\n");sem_op(semid, 1);  // V操作return 0;
}
​

3.3 相关指令

  • ipcs -s:显示当前系统的信号量集。
  • ipcrm -s <semid>:删除指定的信号量集。

四、小项目:生产者-消费者问题

4.1 生产者代码

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>#define SHM_SIZE 1024void sem_op(int semid, int op) {struct sembuf sb;sb.sem_num = 0;sb.sem_op = op;sb.sem_flg = 0;semop(semid, &sb, 1);
}int main() {key_t key = ftok("shmfile", 65);int shmid = shmget(key, SHM_SIZE, 0666 | IPC_CREAT);char *str = (char*) shmat(shmid, (void*)0, 0);key_t sem_key = ftok("semfile", 65);int semid = semget(sem_key, 1, 0666 | IPC_CREAT);union semun sem_union;sem_union.val = 1;semctl(semid, 0, SETVAL, sem_union);while (1) {sem_op(semid, -1);printf("Write Data: ");fgets(str, SHM_SIZE, stdin);sem_op(semid, 1);sleep(1);}shmdt(str);shmctl(shmid, IPC_RMID, NULL);semctl(semid, 0, IPC_RMID);return 0;
}
​

4.2 消费者代码

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>#define SHM_SIZE 1024void sem_op(int semid, int op) {struct sembuf sb;sb.sem_num = 0;sb.sem_op = op;sb.sem_flg = 0;semop(semid, &sb, 1);
}int main() {key_t key = ftok("shmfile", 65);int shmid = shmget(key, SHM_SIZE, 0666 | IPC_CREAT);char *str = (char*) shmat(shmid, (void*)0, 0);key_t sem_key = ftok("semfile", 65);int semid = semget(sem_key, 1, 0666 | IPC_CREAT);while (1) {sem_op(semid, -1);printf("Data read from memory: %s\n", str);sem_op(semid, 1);sleep(1);}shmdt(str);shmctl(shmid, IPC_RMID, NULL);semctl(semid, 0, IPC_RMID);return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词