编写两个程序,利用同一个文件路径进行全局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);
}
}
最终实现效果: