当前位置:网站首页>利用信号灯和共享内存实现进程间同步通信

利用信号灯和共享内存实现进程间同步通信

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);
		
	}

}

最终实现效果:

 

 

原网站

版权声明
本文为[zhouyongku]所创,转载请带上原文链接,感谢
https://blog.csdn.net/zhouyongku/article/details/120908956