进程间共享内存通信(信号量同步)(pyhton发 c++收)

运行环境:ubuntu 20.4
进程间共享内存通信,通过信号量实现进程同步。
创建writer进程,reader进程,writer会每隔一段时间向共享内存写入新的数据,而reader会阻塞地等待并读取这些数据。

上代码:

writer.cpp 文件

// writer.cpp 文件
# writer.py

import time
import mmap
import posix_ipc

SHARED_MEMORY_NAME = "my_shared_memory"
SEM_WRITE_NAME = "sem_write"
SEM_READ_NAME = "sem_read"
MEMORY_SIZE = 1024
DATA = "Data from Python: {}"

# 创建信号量
sem_write = posix_ipc.Semaphore(SEM_WRITE_NAME, posix_ipc.O_CREAT, initial_value=1)
sem_read = posix_ipc.Semaphore(SEM_READ_NAME, posix_ipc.O_CREAT, initial_value=0)

# 创建共享内存
memory = posix_ipc.SharedMemory(SHARED_MEMORY_NAME, posix_ipc.O_CREAT, size=MEMORY_SIZE)
mapfile = mmap.mmap(memory.fd, MEMORY_SIZE)
memory.close_fd()

points = []

point = [111.34,222.33,555.78]
point = [str(item) for item in point]

try:
    while True:
        sem_write.acquire()  # 等待获取写权限

        point_str = ",".join(point) + ";"
        print(point_str)
        message = point_str.encode()
        mapfile.seek(0)
        mapfile.write(message.ljust(MEMORY_SIZE, b'\x00'))  # 在共享内存中写入数据,并用空字节填充
        
        print(f"Written to shared memory: {message.decode()}")

        sem_read.release()  # 释放读信号量,允许读者读取

        time.sleep(1)  # 等待1秒

except KeyboardInterrupt:
    # 释放资源
    sem_write.release()  # 确保释放信号量,以便其他进程可以继续运行或退出
    sem_read.release()
    sem_write.unlink()
    sem_read.unlink()
    mapfile.close()
    memory.unlink()
    print("\nWriter shutdown")
               

reader.cpp 文件

// reader.cpp

#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 

using namespace std;

const char* SHARED_MEMORY_NAME = "/my_shared_memory";
const char* SEM_WRITE_NAME = "/sem_write";
const char* SEM_READ_NAME = "/sem_read";
const int MEMORY_SIZE = 1024;


bool parseStringToVector(const std::string& input, std::vector<std::vector<float>>& result) {
    std::stringstream ss(input);
    std::string line;

    // 解析每一行(由分号分隔)
    while (std::getline(ss, line, ';')) {
        if (line.empty()) continue; // 忽略空行
        std::vector<float> innerVector;
        std::stringstream linestream(line);
        std::string value;

        // 解析每个值(由逗号分隔)
        while (std::getline(linestream, value, ',')) {
            //std::cout << value << std::endl;
            float temp = 0.0;
            try {
                std::size_t lastChar;
                temp = std::stof(value, &lastChar);
                // 检查是否所有的字符都被解析了,也就是确认没有剩余的非数字字符。
                if(lastChar != value.size())
                return false;
            }
            catch (const std::invalid_argument& e) {
                // 无法转换字符串为浮点数
                cout << value << "无法转换字符串为浮点数" << endl;
                return false;
            }
            catch (const std::out_of_range& e) {
                // 数值超出float的范围
                cout << value << "超出范围" << endl;
                return false;
            }
            innerVector.push_back(temp);
        }
        if (innerVector.size() != 3) {
            return false;
        }
        result.push_back(innerVector);
    }

    return true;
}



int main() {
    // 打开共享内存
    int shm_fd = shm_open(SHARED_MEMORY_NAME, O_RDONLY, 0666);
    if (shm_fd == -1) {
        perror("shm_open");
        return 1;
    }

    // 将共享内存映射到进程地址空间
    char* map_ptr = static_cast<char*>(mmap(NULL, MEMORY_SIZE, PROT_READ, MAP_SHARED, shm_fd, 0));
    if (map_ptr == MAP_FAILED) {
        perror("mmap");
        return 1;
    }

    // 打开信号量
    sem_t* sem_write = sem_open(SEM_WRITE_NAME, 0);
    sem_t* sem_read = sem_open(SEM_READ_NAME, 0);
    if (sem_write == SEM_FAILED || sem_read == SEM_FAILED) {
        perror("sem_open");
        return 1;
    }

    // 循环读取共享内存的数据
    while (true) {
        if (sem_wait(sem_read) < 0) {  // 等待写者完成写操作
            perror("sem_wait");
            continue;
        }

        // 读取共享内存的内容
        std::string read_data(map_ptr);
        
	std::vector<std::vector<float>>vec;
	bool  out = parseStringToVector(read_data, vec);
	if (!out) {
		cout << "转换异常" << endl;	
	}

	// 打印解析结果
	for (const auto& innerVec : vec) {
		for (const float& num : innerVec) {
		    std::cout << num << ' ';
		}
		std::cout << std::endl;
	}
        
        
        //std::cout << "Read from shared memory: " << read_data << std::endl;

        if (sem_post(sem_write) < 0) {  // 允许写者进入共享内存区域
            perror("sem_post");
            continue;
        }
    }

    // 清理资源(实际上,由于是无限循环,所以很可能不会执行到这里)
    munmap(map_ptr, MEMORY_SIZE);
    close(shm_fd);
    sem_close(sem_write);
    sem_close(sem_read);

    return 0;
}

编译程序

g++ reader.cpp -o reader -lrt -lpthread

在一个终端中运行数据写入文件

python3 writer.py

在另一个终端中运行读文件

./reader

你可能感兴趣的:(c++,开发语言)