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 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C++】linux 下进程同步例子;实现共享内存、unix 域套接字; -> 正文阅读

[C++知识库]【C++】linux 下进程同步例子;实现共享内存、unix 域套接字;

一、进程同步

1、比较

  • 进程间数据共享: 管道,消息队列,共享内存,unix 域套接字

对比:

  1. 易用性:消息队列 > unix 域套接字 > 管道 > 共享内存(配合信号量使用)
  2. 效率:共享内存 > unix 域套接字 > 管道 > 消息队列
  3. 常用:共享内存,unix 域套接字
  • 异步通讯:信号

  • 同步和互斥: 信号量

2、共享内存实现

  • 进程空间是通过页表,通过段页式存储管理,与实际物理内存建立的映射;
  • 所以进程间也是公用物理内存的;
  • 操作系统的进程管理,使得进程间内存空间独立;进程默认是不能访问进程空间之外的内存空间的;

共享内存:

  • 共享内存,允许不相关的进程访问同一片物理内存;
  • 共享内存是两个进程之间共享和传递数据最快的方式;
  • 共享内存未提供同步机制,需要借助其他机制管理访问;

使用共享内存:

  1. 申请共享内存 : shmget((key_t)1111,sizeof(struct ShmEntry),0666|IPC_CREAT);
  2. 连接到进程空间 : (ShmEntry*)shmat(shmid,0,0);连接到
  3. 使用共享内存
  4. 脱离进程空间&& 删除 : shmdt(entry); && shmctl(shmid,IPC_RMID,0);
#ifndef __COMMON_H_
#define __COMMON_H_

#define TEXT_LEN 2048

struct ShmEntry{
	bool can_read;
	char msg[2048];
};
  • server
#include "common.h"

#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#include <iostream>
int main()
{
	struct ShmEntry *entry;
	int shmid = shmget((key_t)1111,sizeof(struct ShmEntry),0666|IPC_CREAT);
	if(shmid ==-1)
	{
		std::cout<<"creat error!"<<std::endl;
		return -1;
	}
	std::cout<<"yes! "<<std::endl;
	entry = (ShmEntry*)shmat(shmid,0,0);
	entry->can_read = 0;
	while(true){
		if(entry->can_read == 1)
		{
			std::cout<<"msg : "<<entry->msg<<std::endl;
			entry->can_read = 0;
		}
		else
		{
			std::cout<<" sleep 1 second"<<std::endl;
			sleep(1);
		}
	}
	shmdt(entry);
	
	shmctl(shmid,IPC_RMID,0);
return 0;
}

  • client
#include "common.h"

#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#include <iostream>
int main()
{
	struct ShmEntry *entry;
	int shmid = shmget((key_t)1111,sizeof(struct ShmEntry),0666|IPC_CREAT);
	if(shmid ==-1)
	{
		std::cout<<"creat error!"<<std::endl;
		return -1;
	}
	std::cout<<"yes! "<<std::endl;
	entry = (ShmEntry*)shmat(shmid,0,0);
	entry->can_read = 0;
	char buffer[TEXT_LEN];
	while(true){
		if(entry->can_read == 0)
		{
			std::cout<<"input message: "<<std::endl;
			fgets(buffer,TEXT_LEN,stdin);
			strncpy(entry->msg,buffer,TEXT_LEN);
			
	
			entry->can_read = 1;
		}
	}

	shmdt(entry);
	
	shmctl(shmid,IPC_RMID,0);
return 0;
}
g++ server .cpp common.h -o server -g -lpthread
g++ client.cpp common.h -o client -g -lpthread
  • 实现
    在这里插入图片描述

3、Unix 域套接字实现

  • 套接字本是网络通信;
  • Unix系统提供的域套接字提供了网络套接字类似功能;
  • 他提供了单机、简单、可靠的进程通信同步服务;
  • 只能单机使用,不能跨机器使用;跨机器需要网络套接字;
  • 相比共享内存,提供的是可靠的信息传递,不需要维护同步信息;
  • Nginx 、 uWSGI 、 都会使用到;

server使用:

  1. 创建套接字
  2. 绑定套接字
  3. 监听套接字
  4. 接收&处理信息

client使用:

  1. 创建套接字
  2. 连接套接字
  3. 发送信息
  • server.cpp
#include <sys/types.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <netinet/in.h>
#include <iostream>

#define SOCKET_PATH "./domainsocket"
#define MSG_SIZE 2048
using namespace std;
int main()
{
	int socket_fd, accept_fd;
	int ret = 0;
	socklen_t addr_len;
	char msg[MSG_SIZE];
	struct sockaddr_un server_addr;
	//1
	socket_fd = socket(PF_UNIX,SOCK_STREAM,0);
	if (-1 == socket_fd)
	{
		cout << "socket create failed" << endl;
		return -1;
	}

	remove(SOCKET_PATH);

	bzero(&server_addr, sizeof(server_addr));
	server_addr.sun_family = PF_UNIX;
	strcpy(server_addr.sun_path, SOCKET_PATH);

	cout << "binding " << endl;
	//2
	ret = bind(socket_fd, (sockaddr*)&server_addr, sizeof(server_addr));
	if (0 > ret)
	{
		cout << "bind socket failed" << endl;
		return -1;
	}
	//3
	cout << "listening " << endl;
	ret = listen(socket_fd, 10);
	if (-1 == ret)
	{
		cout << "listen failed" << endl;
		return -1;
	}
	cout << "waiting new requests " << endl;
	accept_fd = accept(socket_fd, NULL, NULL);

	bzero(msg, MSG_SIZE);

	while (1)
	{
		//4
		recv(accept_fd, msg, MSG_SIZE, 0);
		cout << "received message : " << msg<<endl;
	}
	close(accept_fd);
	close(socket_fd);
	return 0;
}
  • client.cpp
#include <sys/types.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <netinet/in.h>
#include <iostream>

#define SOCKET_PATH "./domainsocket"
#define MSG_SIZE 2048
using namespace std;
int main()
{
	int socket_fd;
	int ret = 0;
	char msg[MSG_SIZE];
	struct sockaddr_un server_addr;
	//1
	socket_fd = socket(PF_UNIX,SOCK_STREAM,0);
	if (-1 == socket_fd)
	{
		cout << "socket create failed" << endl;
		return -1;
	}

	bzero(&server_addr, sizeof(server_addr));
	server_addr.sun_family = PF_UNIX;
	strcpy(server_addr.sun_path, SOCKET_PATH);

	cout << "connecting " << endl;
	//2
	ret = connect(socket_fd, (sockaddr*)&server_addr, sizeof(server_addr));
	if (-1 == ret)
	{
		cout << "bind socket failed" << endl;
		return -1;
	}

	while (1)
	{
		cout << "Input message >>> ";
		fgets(msg, MSG_SIZE, stdin);
		//3
		ret = send(socket_fd, msg, MSG_SIZE,0);
	}

	close(socket_fd);
	return 0;
}
g++ server.cpp -o server -g -lpthread
g++ client.cpp -o client -g -lpthread

实现:
在这里插入图片描述

参考

【学习笔记】【操作系统】

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-10 14:21:50  更:2021-07-10 14:21:59 
 
开发: 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年5日历 -2024/5/4 5:41:38-

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