IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 进程间通信 -> 正文阅读

[系统运维]进程间通信

一、命名管道FIFO

FIFO IPC机制:利用文件系统中系统文件来标识的。可以用mkfifo命令创建一个FIFO文件:

mkfifo?tube

ls -l tube

FIFO文件在磁盘上没有数据块,仅用来标识内核中的一条通道,各进程可以打开这个文件进行read/write,实际上是在读写内核通道(根本原来在于file结构体所指向的read,write函数和常规文件不一样),就实现了进程间通信。

二、共享内存

1.共享存储

允许两个或多个进程共享一给定的存储区。因为数据不需要再客户机和服务器之间复制。

2.调用第一个函数是shmget,获得一个指定大小的共享存储标识符。

①key:用来标识共享内存size参数该共享存储段最小值,如果正在创建一个新段,必须指定size。如果正在存放一个现存的段,将size指定为0。

②shmflg:IPC_CREATE和IPC_EXCL,最为重要的是shmflg中指明访问权限,跟open的mode参数一样。否则出现permission denied错误。

③返回:若成功则为共享内存ID,出错则为-1。

④key由ftok()生成。pathname必须为调用进程可以访问的。pathname和proj_id共同组成一个key。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>


int main(void) {
    key_t key = ftok("./9_1readfifo.c", 9);
    if (key < 0) {
        perror("ftok");
        exit(1);
    }
    printf("key=0x%x\n", key);

    int shmid = shmget(key, 20, IPC_CREAT  | 0666);
    if (shmid < 0) {
        perror("shmget");
        exit(1);
    }
    printf("shmid=%d\n", key);
    return 0;
}

3.调用一旦创建一个共享存储段,进程就可调用shmat将其连接到它的地址空间中。

①返回:若成功则为指向共享存储段的指针,出错则为-1.

②共享存储段连接到调用进程的哪个地址上与addr参数以及flag中是否指定SHM_RND位有关:

如果addr=NULL:此段连接到由内核选择的第一个可用地址上。

如果addr非NULL,并没有指定SHM_RND:此段连接到addr指定的地址上。

如果addr非0,并且指定SHM_RND:此段连接到addr-(addr mod SHMLBA)表示的地址上。

SHM_RND:取整。

SHM_LBA:低边界地址倍数,总是2的乘方。

该算式将地址向下取最近1个SHMLBA的倍数。

③一般指定addr=0,以便由内核选择地址。

?

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>


int main(void) {
    key_t key = ftok("./9_1readfifo.c", 9);
    if (key < 0) {
        perror("ftok");
        exit(1);
    }
    printf("key=0x%x\n", key);

    int shmid = shmget(key, 20, IPC_CREAT  | 0666);
    if (shmid < 0) {
        perror("shmget");
        exit(1);
    }
    printf("shmid=%d\n", key);

    void *shmp = shmat(shmid, NULL, 0);
    if (shmp < 0) {
        perror("shmat");
        exit(1);
    }
    printf("shmp=%p\n", shmp);
    pid_t pid = fork();
    if (pid < 0) {
        perror("fork");
        exit(1);
    }
    if (pid) {
        //parent process
        while (1) {
            scanf("%s", shmp);
            if (!strcmp(shmp, "quit")) break;
        }
        wait(NULL);
    } else {
        //child process
        while (1) {
            if (!strcmp(shmp, "quit")) break;
            if (shmp) {
                printf("child read %s\n", shmp);
                bzero(shmp, 20);
            }
            sleep(1);
        }
    }
    shmdt(shmp);
    return 0;
}

?

4.调用当对共享存储段的操作已经结束时,则调用shmdt脱接该段。

(并不从系统中删除其标识符以及其数据结构。该标识符依然存在直到某个进程调用shmctl带命令IPC_RMID特地删除它)

shmaddr参数:以前调用shmat时返回值:返回成功为0,错误为-1.

5.调用shmctl对共享存储段执行多种操作

三、消息队列

1.系统内核维护一个存放消息的队列,不同用户可以向队列中发送信息或者队列中接收消息。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/msg.h>

int main() {
    key_t key = ftok("./tube", 9);
    printf("mqid=%#x\n", key);
    int mqid = msgget(key, IPC_CREAT | 0666);
    printf("mqid=%d\n", mqid);
    return 0;
}

2.往队列里发送一条消息。此操作被中断后不会被重启(信号处理中SA_RESTART)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/msg.h>

#define MSGLEN 20

typedef struct msgbuf
{
    long mtype;
    char mtext[MSGLEN];
}MSG;


int main() {
    key_t key = ftok("./tube", 9);
    printf("mqid=%#x\n", key);
    int mqid = msgget(key, IPC_CREAT | 0666);
    printf("mqid=%d\n", mqid);

    MSG msg;
    msg.mtype = 1;
    strncpy(msg.mtext, "how are you?\n", MSGLEN);
    msgsnd(mqid, &msg, MSGLEN, 0);

    msg.mtype = 2;
    strncpy(msg.mtext, "haha\n", MSGLEN);
    msgsnd(mqid, &msg, MSGLEN, 0);
    return 0;
}

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/msg.h>

#define MSGLEN 20

typedef struct msgbuf
{
    long mtype;
    char mtext[MSGLEN];
}MSG;


int main() {
    key_t key = ftok("./tube", 9);
    printf("mqid=%#x\n", key);
    int mqid = msgget(key, IPC_CREAT | 0666);
    printf("mqid=%d\n", mqid);

    MSG msg;
    msgrcv(mqid, &msg, MSGLEN, 2, 0);
    printf("msg.type=%ld\nmsg,text=%s\n", msg.mtype, msg.mtext);

    msgrcv(mqid, &msg, MSGLEN, 1, 0);
    printf("msg.type=%ld\nmsg,text=%s\n", msg.mtype, msg.mtext);
    return 0;
}

?

?

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-02-07 14:03:25  更:2022-02-07 14:05:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 5:55:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码