当前位置:网站首页>利用信号灯和共享内存实现进程间同步通信
利用信号灯和共享内存实现进程间同步通信
2022-08-09 13:05:00 【zhouyongku】
编写两个程序,利用同一个文件路径进行全局Key创建,然后创建两个信号灯,一个是读通知,一个是写通知。
发送端:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<unistd.h>
#include<time.h>
#include<sys/time.h>
#include<sys/sem.h>
using namespace std;
#define LIGHT_READ 0
#define LIGHT_WRITE 1
long long syslocaltime()
{
struct timeval tmstart;
gettimeofday(&tmstart,NULL);
long long a=tmstart.tv_sec*1000+tmstart.tv_usec/1000;
printf("second=%lld,usec=%lld",tmstart.tv_sec,tmstart.tv_usec);
}
void Wait(int semid,int nId) //占用资源(拿走绿灯)
{
struct sembuf sops;
sops.sem_num = nId; /* 要操作的信号量的编号为0 */
sops.sem_op = -1; /* Wait for value to equal 0 */
sops.sem_flg = 0; /* 既不IPC_NOWAIT,也不IPC_UNDO */
printf("wait semop start semid=%d,channel=%d\n",semid,nId);
if (semop(semid, &sops, 1) == -1)
{
printf("wait semop failed, infor\r\n" );
}
else
{
printf("wait semop success semid=%d,channel=%d\n",semid,nId);
}
}
void Post(int semid,int nId) //释放资源(归还绿灯)
{
struct sembuf sops;
sops.sem_num = nId; /* 要操作的信号量的编号为0 */
sops.sem_op = 1; /* Wait for value to equal 0 */
sops.sem_flg = 0; /* 既不IPC_NOWAIT,也不IPC_UNDO */
printf("wait semop start semid=%d,channel=%d\n",semid,nId);
if (semop(semid, &sops, 1) == -1)
{
printf("post semop failed, infor\r\n" );
}
else
{
printf("post semop success semid=%d,channel=%d\n",semid,nId);
}
}
const int MAX_BUF_SIZE=1000*1000;
const int listlen=10;
int main(int argc,char ** argv )
{
int nkey= ftok("/mnt/hgfs/E/code/基线代码/ftokcode",33);
printf("ftok return k=%d\n",nkey);
if( nkey <0 )
{
perror("testcli");
return -1;
}
int id=shmget(nkey,MAX_BUF_SIZE,IPC_CREAT);
printf("shmget id=%d\n",id);
if( id< 0 )
{
perror("shmget");
return -2;
}
void *pAddr=shmat(id,NULL,0);
if( NULL == pAddr )
{
perror("shmat");
return -3;
}
int semid = semget(id, 2, IPC_CREAT | 0666 );//0--read enable ---1 write enable
if(-1 == semid)
{
return -1;
}
else
{
printf("semget by id=%d ok, semid = %d\n", id,semid );
}
Post(semid,LIGHT_WRITE);
int i=0,j=0;
while( true )
{
sleep(10);
Wait(semid,LIGHT_WRITE);
char *p = (char*)pAddr;
char szMsg[100]={0};
printf((char*)pAddr+10);
*p=1;
FILE * fp = fopen("./send.jpg","rb");
if( fp==NULL )
{
printf("read send.jpg error\n");
return -4;
}
else
{
printf("open ./send.jpg success\n");
}
fseek(fp,0,SEEK_END);
int nLen = ftell( fp);
fseek(fp,0,SEEK_SET);
int nDataLen = fread(p+100,1,nLen,fp );
if( nDataLen>MAX_BUF_SIZE )
{
fclose( fp );
printf("image buf=%d is mothan %d-100",nDataLen,MAX_BUF_SIZE);
return -4;
}
else
{
printf("ftell=%d,read=%d\n",nLen,nDataLen);
}
int *pImageSize= (int*)(pAddr+4);
*pImageSize=nLen;
sprintf( (char*)pAddr+10,"hello:my name is %s, i=%d,j=%d,file size=%d,byte=(%d,%d,%d,%d)\n","testcli",i++,j++,nLen,*(p+4),*(p+5),*(p+6),*(p+7));
fclose(fp);
Post(semid,LIGHT_READ);
}
}
接收端
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<unistd.h>
#include<time.h>
#include<sys/time.h>
#include<sys/sem.h>
using namespace std;
#define LIGHT_READ 0
#define LIGHT_WRITE 1
long long syslocaltime()
{
struct timeval tmstart;
gettimeofday(&tmstart,NULL);
long long a=tmstart.tv_sec*1000+tmstart.tv_usec/1000;
printf("second=%lld,usec=%lld",tmstart.tv_sec,tmstart.tv_usec);
}
void Wait(int semid,int nId) //占用资源(拿走绿灯)
{
struct sembuf sops;
sops.sem_num = nId; /* 要操作的信号量的编号为0 */
sops.sem_op = -1; /* Wait for value to equal 0 */
sops.sem_flg = 0; /* 既不IPC_NOWAIT,也不IPC_UNDO */
printf("wait semop start semid=%d,channel=%d\n",semid,nId);
if (semop(semid, &sops, 1) == -1)
{
printf("wait semop failed, infor\r\n" );
}
else
{
printf("wait semop success semid=%d,channel=%d\n",semid,nId);
}
}
void Post(int semid,int nId) //释放资源(归还绿灯)
{
struct sembuf sops;
sops.sem_num = nId; /* 要操作的信号量的编号为0 */
sops.sem_op = 1; /* Wait for value to equal 0 */
sops.sem_flg = 0; /* 既不IPC_NOWAIT,也不IPC_UNDO */
printf("wait semop start semid=%d,channel=%d\n",semid,nId);
if (semop(semid, &sops, 1) == -1)
{
printf("post semop failed, infor\r\n" );
}
else
{
printf("post semop success semid=%d,channel=%d\n",semid,nId);
}
}
const int MAX_BUF_LEN=1000*1000;
const int listlen=10;
int main(int argc,char ** argv )
{
int nkey= ftok("/mnt/hgfs/E/code/基线代码/ftokcode",33);
printf("ftok return k=%d\n",nkey);
if( nkey <0 )
{
perror("testcli");
return -1;
}
int id=shmget(nkey,MAX_BUF_LEN,IPC_CREAT);
printf("shmget id=%d\n",id);
if( id< 0 )
{
perror("shmget");
return -2;
}
void *pAddr=shmat(id,NULL,0);
if( NULL == pAddr )
{
perror("shmat");
return -3;
}
int semid = semget(id, 2, IPC_CREAT | 0666 );//0--read enable ---1 write enable
if(-1 == semid)
{
return -1;
}
else
{
printf("semget by id=%d ok, semid = %d\n", id,semid );
}
int i=0,j=0;
while( true )
{
usleep(1);
Wait(semid,LIGHT_READ);
//char szMsg[100]={0};
//sprintf( (char*)pAddr,"hello:my name is %s, i=%d,j=%d\n","testcli",i++,j++);
char *p=(char*)pAddr;
//if( *p==1 )
//{
char szFileName[100]={0};
sprintf( szFileName,"./recv%d.jpg",i++);
FILE *fp = fopen(szFileName,"wb");
if( NULL == fp )
{
printf("open file %s error\n",szFileName);
return -4;
}
else
{
printf("create file %s success\n",szFileName);
}
int nImageSize= *((int*)(pAddr+4));
printf((char*)pAddr+10);
int nTotalLen = 0;
int nLen = fwrite(p+100,1,nImageSize,fp);
syslocaltime();
printf("image %s len=%d,writelen=%d\n",szFileName,nImageSize,nLen);
fclose(fp);
//std::this_thread::sleep_for(std::chrono::seconds(1));
*p=0;
//}
//sleep(1);
Post(semid,LIGHT_WRITE);
}
}
最终实现效果:


边栏推荐
猜你喜欢
随机推荐
剑指 Offer 56 - II. 数组中数字出现的次数 II(位运算)
陈强教授《机器学习及R应用》课程 第十六章作业
Professor Chen Qiang the machine learning and R application course chapter 18 assignments
An Offer 21. Adjust the array in order to make odd in even the front (loop invariant)
read stream special attention
为什么文字不贴合边
Time series analysis course lab report
render解析
面试攻略系列(三)-- 高级开发工程师面试问些啥?
R 语言 2010.1至2021.12艾滋病每月发病人数 时间序列分析
NC15 求二叉树的层序遍历
Uni - app - uview Swiper shuffling figure component, click on the links to jump (click to get the item after the row data, remove data operation)
5G China unicom AP:B SMS ASCII 转码要求
kustomize entry example and basic syntax instructions
NFS pays special attention to the problem of permissions
LeetCode 37.解数独
5G 联通网管设计思路
Professor Chen Qiang's "Machine Learning and R Application" course Chapter 16 Assignment
GIN文件上传与返回
NC193 二叉树的前序遍历









