当前位置:网站首页>利用信号灯和共享内存实现进程间同步通信
利用信号灯和共享内存实现进程间同步通信
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);
}
}
最终实现效果:
边栏推荐
猜你喜欢
随机推荐
Professor Chen Qiang's "Machine Learning and R Application" course Chapter 16 Assignment
ARM board adds routing function
联通网管协议框图
43. The sword refers to Offer 1 ~ 1 the number of occurrences of n integers (recursive, mathematics)
Periodic sharing of Alibaba Da Tao system model governance
Professor Chen Qiang's "Machine Learning and R Application" course Chapter 13 Assignment
现在40系显卡都快出来了,为何1060型号的显卡还有这么多人用?
JS本地存储 sessionStorage和localStorage
陈强教授《机器学习及R应用》课程 第十三章作业
面试攻略系列(四)-- 你不知道的大厂面试
Standing wave ratio calculation method
Explanation of RTSP protocol
render解析
How to solve the 0x80070005 error when the computer is reinstalled and the system is restored
GET POST PUT DELETE request in GIN
Rmarkdown Tutorial
Professor Chen Qiang's "Machine Learning and R Application" course Chapter 15 Homework
GIN初探,环境安装
【NVIDIA】Tesla V100安装NVIDIA-Driver驱动程序适配CUDA-Toolkit-11.6
Professor Chen Qiang's "Machine Learning and R Application" course Chapter 14 Assignment