吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2214|回复: 9
收起左侧

[C&C++ 原创] Linux中基于的共享内存的两进程之间的实时通信

[复制链接]
nbzlk 发表于 2022-12-6 10:13

两个进程的代码大抵相同,只有对信号量的处理有一点区别。

第一次的提示显示有的bug😅
还在学习中

思路:每个进程创建一个自己的线程,这个线程根据信号量来决定是否要进入读取内容的判读,如果进入,则开始进行共享内存中是否有内容,有就取出来,没有就进行下一次的循环。

结果

zlk_Snipper - Snipaste_2022-12-06_10-11.png

a进程源码

#include <stdio.h>
#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>

#define SHM_SIZE 128

char *p = NULL;
sem_t *sem1 = NULL, *sem2 = NULL;

void fun(int signo)
{
    shmdt(p); // 取消对共享空间的映射
    sem_close(sem1); // 关闭信号量,内核中没有删除
    sem_close(sem2);
    sem_unlink("zlk"); // 删除信号量
    exit(0);
    return ;
}

void *jieshou(void *arg)
{
    while(1)
    {
        // 在阻塞的时候无操作
        sem_wait(sem1);
        if(*p != 0)
        {
            //printf("收到:%s\r\n", p);
            printf("收到:%s", p);
            memset(p, 0, sizeof(SHM_SIZE));
        }
    }
}

int main(int argc, char *argv[])
{
    // 信号量部分
    sem1 = sem_open("shou", O_CREAT, 0666, 0); // 设置信号量sem1的初始化值为0
    if(SEM_FAILED == sem1) // 判断信号量是否创建成功
    {
        perror("sem_open error");
        return -1;
    }
    sem2 = sem_open("fa", O_CREAT, 0666, 0); 
    if(SEM_FAILED == sem2) // 判断信号量是否创建成功
    {
        perror("sem_open error");
        return -1;
    }
    // 共享内存部分
    key_t key = ftok(".", 22);
    if(-1 == key)
    {
        perror("ftok error");
        return -1;
    }
    int shmId = shmget(key, SHM_SIZE, IPC_CREAT | 0666); // 生成一个共享空间
    if(-1 == shmId)
    {
        perror("shmget error");
        return -1;
    }
    p = (char *)shmat(shmId, NULL, 0); // 在私有空间中建立共享内存的映射
    if((void *)-1 == p)
    {
        perror("shmat error");
        return -1;
    }
    memset(p, 0, sizeof(SHM_SIZE)); // 清空原先空间里的内容
    printf("--------zlk------------\r\n");

    // 创建一个线程,用于监听收到的信息
    pthread_t tID = -1;
    if(0 != pthread_create(&tID, NULL, jieshou, NULL))
    {
        printf("creater pthread error\r\n");
        return -1;
    }

    while(1)
    {
        signal(SIGINT, fun); // 收到Ctrl + c后调用自定义fun函数
        printf("发送:\r\n");
        fgets(p, SHM_SIZE, stdin);
        sem_post(sem2); // 使sem2加1
    }
    return 0;
}

b进程源码

#include <stdio.h>
#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>

#define SHM_SIZE 128

char *p = NULL;
sem_t *sem1 = NULL, *sem2 = NULL;

void fun(int signo)
{
    shmdt(p); // 取消对共享空间的映射
    sem_close(sem1); // 关闭信号量,内核中没有删除
    sem_close(sem2);
    sem_unlink("zlk"); // 删除信号量
    exit(0);
    return ;
}

void *jieshou(void *arg)
{
    while(1)
    {
        sem_wait(sem2);
        if(*p != 0)
        {
            printf("收到:%s", p);
            memset(p, 0, sizeof(SHM_SIZE));
        }
    }
}

int main(int argc, char *argv[])
{
    // 信号量部分
    sem1 = sem_open("shou", O_CREAT, 0666, 0); // 设置信号量sem1的初始化值为0
    if(SEM_FAILED == sem1) // 判断信号量是否创建成功
    {
        perror("sem_open error");
        return -1;
    }
    sem2 = sem_open("fa", O_CREAT, 0666, 0); 
    if(SEM_FAILED == sem2) // 判断信号量是否创建成功
    {
        perror("sem_open error");
        return -1;
    }
    // 共享内存部分
    key_t key = ftok(".", 22);
    if(-1 == key)
    {
        perror("ftok error");
        return -1;
    }
    int shmId = shmget(key, SHM_SIZE, IPC_CREAT | 0666); // 生成一个共享空间
    if(-1 == shmId)
    {
        perror("shmget error");
        return -1;
    }
    p = (char *)shmat(shmId, NULL, 0); // 在私有空间中建立共享内存的映射
    if((void *)-1 == p)
    {
        perror("shmat error");
        return -1;
    }
    printf("--------ylx------------\r\n");
    // 创建一个线程,用于监听收到的信息
    pthread_t tID = -1;
    if(0 != pthread_create(&tID, NULL, jieshou, NULL))
    {
        printf("creater pthread error\r\n");
        return -1;
    }
    while(1)
    {
        signal(SIGINT, fun); // 收到Ctrl + c后调用自定义fun函数
        printf("发送:\r\n");
        fgets(p, SHM_SIZE, stdin);
        sem_post(sem1); // 使sem1加1
    }
    return 0;
}

免费评分

参与人数 2吾爱币 +4 热心值 +2 收起 理由
Bert001 + 1 + 1 不错
wushaominkk + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

AyyArr 发表于 2022-12-6 11:18
6666可以 可以
netdata 发表于 2022-12-6 12:19
lfordch 发表于 2022-12-6 12:47
wuditieniu 发表于 2023-7-12 08:53
学习了,最近正在学习linux进程通信方面的
BinaryHK 发表于 2023-10-31 13:07
感谢分享,,收藏了
lalala518 发表于 2023-11-2 09:35
感谢分享,学习一下
liuxf09 发表于 2023-12-29 13:56
感谢分享,学习了
sihaitangzhu666 发表于 2024-3-4 20:13
先收藏, 正在搞这方面的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 17:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表