⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipc.c

📁 linux下串口的访问
💻 C
字号:
#include <stdio.h> 
#include <string.h>
#include <stdlib.h>  
#include "ipc.h"

#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/msg.h>	// System V Message queue
#include <sys/sem.h>	// System V semaphore
#include <semaphore.h>	// Posix semaphore
#include <fcntl.h>	// for O_RDWR
#include <errno.h>	// for errno, EEXIST
#include <sys/stat.h> 




//////////////////////////////////////////////////////////////////////////
int CreateChildProcess( int (*proc)(void) )		
{
	pid_t pid;
	int   ret;
	
	switch (pid = fork()) 
	{
	case -1:	/* error */
		perror("fork");
		return -1;
	case 0:		/* child */
		ret = proc();
		exit(ret);
	default:	/* parent */
		break;
	}
	return pid;
}


//////////////////////////////////////////////////////////////////////////
// System V Message queue

int MsgIdGet( int key )
{
	int id;

	//id  = msgget(key,0);
	id = msgget( key, IPC_CREAT|0666 );
	if ( id < 0 )
	{
		perror("msgget error.");
		return -1;
	}
	return id;
}

int MsgRecv( int id, unsigned char * buf, int type )
{
	int len;
	struct { 
		long msg_type; 
		char msg_data[MsgDataLen]; 
         } rMsg; 

	if ( buf==0 )
	{
		printf("para error.\n");
		return -1;
	}
	type = type <0 ? -type : type;	// type must more than 0
	len = msgrcv(id, (char *)&rMsg, MsgDataLen, type, 0 ); 
	if ( len<0 || len>MsgDataLen )
	{
		perror("msgrcv error.");
		return -1;
	}
	memcpy( buf, rMsg.msg_data, len );
	return len;
} 

int MsgSend( int id, unsigned char * buf, int buflen, int type )
{
	int ret;
	struct { 
		long msg_type; 
		char msg_data[MsgDataLen]; 
         } rMsg; 
	
	if ( buf==0 || buflen<0 )
	{
		printf("para error.\n");
		return -1;
	}

	memcpy( rMsg.msg_data, buf, buflen );
	type = type <0 ? -type : type;	// type must more than 0
	rMsg.msg_type = type;
	ret = msgsnd(id, (char *)&rMsg, buflen, 0 ); 
	if ( ret<0 )
	{
		perror("msgsnd error.");
		return -1;
	}
	return ret;	
} 

int MsgDele( int id )
{
	if( msgctl(id,IPC_RMID,(struct msqid_ds*)0)<0 ) 
	{
		perror("can't PMIN message queue 1.\n"); 
		return -1;
	}
	return 0;
}

/*
int main(int argc, char *argv[])
{
// 	if ( argc < 2 )
// 	{
// 		printf("para too less\n");
// 		return -1;
// 	}

	int id = MsgIdGet( 123321 );
	char buf[32];

	printf("id=%d\n",id);
	int fid;

	fid = fork();
	if ( fid==0 )
	{
		printf("Send hello...\n");
		printf( "ret=%d\n", MsgSend( id, "hello", 6, 1 ) );
		printf("Send end\n");
		exit(0);
	}

	printf("Recv ...\n");
	printf( "ret=%d\n", MsgRecv( id, buf, 1 ) );
	printf("Buf:%s\n", buf);
	

// 	if ( argv[1][0]=='s' )
// 	{
// 		printf("Send hello...\n");
// 		printf( "ret=%d\n", MsgSend( id, "hello", 6, 1 ) );
// 		printf("Send end\n");
// 	}
// 	else
// 	{
// 		printf("Recv ...\n");
// 		printf( "ret=%d\n", MsgRecv( id, buf, 1 ) );
// 		printf("Buf:%s\n", buf);
// 	}
	//MsgDele(id);
	return 0;
}

//*/




//////////////////////////////////////////////////////////////////////////
// System V Semaphore

// #define MAX_TRIES	10
// #define SEM_R		0400
// #define SEM_A		0200
// #define SVSEM_MODE	(SEM_R|SEM_A|SEM_R>>3|SEM_R>>6)	// default permissions for new SV message semaphore

#define SEM_PERM	0600


union semun
{
	int		 val;	// used for SETVAL only
	struct semid_ds	*buf;	// used for IPC_SET and IPC_STAT
	unsigned short	*array;	// used for GETALL and SETALL
};

static struct sembuf LockOp[2]=
{
        0,0,0,
	0,1,SEM_UNDO
};

static struct sembuf UnlckOp[1]=
{
        0,-1,(IPC_NOWAIT|SEM_UNDO)
};


//struct sembuf postop, waitop;

// create semaphore, open it if it was created.
// return semid
int SemCreate( char *path )
{
	int semid;

	if (path==NULL)
		return -1;
	
	unlink( path );
	semid = semget(ftok(path,0),1,SEM_PERM|IPC_CREAT|IPC_EXCL);
	if( semid<0 )
	{
		perror("Create semaphore error");
		return -1;
	}
	return semid;

// 	int		semid;
// 	union semun	arg;
// 	struct semid_ds seminfo;
// 	int             i;
// 
// 	semid = semget( ftok(LOCK_PATH,0), 1, IPC_CREAT|IPC_EXCL|SVSEM_MODE);
// 	printf("simid=%d\n", semid);
// 	if ( semid>=0 )
// 	{
// 		arg.val = 1;
// 		semctl( semid, 0, SETVAL, arg );
// 		postop.sem_num = 0;
// 		postop.sem_op  = 1;
// 		postop.sem_flg = SEM_UNDO;
// 		waitop.sem_num = 0;
// 		waitop.sem_op  = -1;
// 		waitop.sem_flg = SEM_UNDO;
// 	}
// 	else if (errno==EEXIST)  // if exist then open it.
// 	{
// 		// someone else has created; make sure it's initialized
// 		semid   = semget( ftok(LOCK_PATH,0), 1, SVSEM_MODE);
// 		arg.buf = &seminfo;
// 		for ( i=0; i<MAX_TRIES; i++ )
// 		{
// 			semctl( semid, 0, IPC_STAT, arg );
// 			if ( arg.buf->sem_otime != 0 )	// it's initialized
// 				break;
// 			sleep(1);
// 		}
// 		perror("semget ok, buf semaphore not initialized");
// 		return -1;
// 	}
// 	else
// 	{
// 		perror("semget error");
// 		return -1;
// 	}
// 	return 0;
}

int SemLock( char *path )
{
	int semid;
	
	if (path==NULL)
		return -1;

	semid = semget(ftok(path,0),1,SEM_PERM|IPC_CREAT);
	
	//printf("semid=%d\n", semid);
        if( semid < 0 )
        {
                perror("LockSem() Get semaphore error");
		return -1;
        }

        if(semop(semid,&LockOp[0],2)==-1)	// down by 1
        {
                perror("LockSem() Lock semaphore error");
		return -1;
        }
	return 0;
}

int  SemUnlock( char *path )
{
	int semid;
	
	if (path==NULL)
		return -1;
	
	semid = semget(ftok(path,0),1,SEM_PERM|IPC_CREAT);
	//printf("semid=%d in SemUnlock\n", semid);
        if( semid < 0 )
        {
                perror("LockSem() Get semaphore error");
		return -1;
        }
        if(semop(semid,&UnlckOp[0],1)==-1)	// up by 1	
        {
                perror("UnlkSem() Unlock semaphore error");
		return -1;
        }
	return 0;
}


void SemDele( char *path )
{
	int semid;
	
	if (path==NULL)
		return ;
	
	semid = semget(ftok(path,0),1,SEM_PERM|IPC_CREAT);
	
        if( semid < 0 )
        {
                perror("LockSem() Get semaphore error");
		return ;
        }

	//       删除信号灯semid              
	if(semctl(semid,0,IPC_RMID,0)==-1)
	{
		perror("Remove semaphore memory error");
	}
}

//*
//#define LOCK_PATH	"/tmp/WSemaphorexx1"

// int semfn(void)
// {
// 	usleep(200);
// 	while ( 1 )
// 	{
// 		printf("wait unlock....\n");
// 		SemLock( LOCK_PATH );	
// 		printf("ok, pid:%d\n", getpid() );
// 		sleep(1);
// 		//SemUnlock( NULL );
// 	}	
// }


// int main(void)
// {
// 	CreateChildProcess( semfn );
// 	char c;
// 	int sid;
// 	//SemDele(NULL);
// 	
// 	//sid = SemCreate(LOCK_PATH);
// 	//printf("sid:%d\n", sid );
// 	SemLock( LOCK_PATH );	
// 	printf("input a char: " );
// 	while ( (c=getchar())!='x' )
// 	{
// 		if (c=='u')
// 		{
// 			printf("unlock\n" );
// 			SemUnlock( LOCK_PATH );
// 		}
// // 		if (c=='l')
// // 		{
// // 			printf("SemLock\n" );
// // 			SemLock( NULL );	
// // 		}
// // 		if (c=='d')
// // 		{
// // 		}
// 	}	
// 	printf("Delete sem\n" );
// 	SemDele(LOCK_PATH);	
// 	return 1;
// }

//*/


//////////////////////////////////////////////////////////////////////////
// Posix Semaphore

sem_t * PosixSemCreate( const char * name )
{
	sem_t *	sem;

	if (name==NULL)
		return NULL;
	printf("PosixSemCreate\n");
	sem = sem_open( name, O_RDWR | O_CREAT, 0600, 1 );
	printf("sem:%p\n", sem);
	if ( sem==SEM_FAILED )
	{
		perror("sem create error");
		return NULL;
	}
	return sem;
}

int PosixSemDele( const char * name )
{
	if (name==NULL)
		return -1;
		
	return sem_unlink( name );
}

int PosixSemWait( const char * name )
{
	sem_t *	sem;
	int     ret;
	
	if (name==NULL)
		return -1;
	
	sem = sem_open( ( name ), 0 );
	if ( sem==SEM_FAILED )
	{
		perror("sem open error.");
		return -1;
	}
	ret =  sem_wait( sem );
	if ( ret<0 )
	{
		perror("sem_wait error.");
	}
	return ret;
}

int PosixSemPost( const char * name )
//int PosixSemPost( sem_t *	sem )
{
	sem_t *	sem;
	int     ret;
	
	if (name==NULL)
		return -1;
	
	sem = sem_open( ( name ), 0 );
	if ( sem==SEM_FAILED )
	{
		perror("sem open error.");
		return -1;
	}
	ret =  sem_post( sem );
	if ( ret<0 )
	{
		perror("sem_post error.");
	}
	return ret;
}

// gcc ipc.c  -o ipc  -lrt or -lpthread

#define LOCK_PATH	"/tmp/posixsem"

int semfn(void)
{
	printf("child ipc start...");

	usleep(200);
	while ( 1 )
	{
		printf("wait ....\n");
		int ret = PosixSemWait( LOCK_PATH );	
		printf("ok, child pid:%d, ret=%d\n", getpid(), ret );
		sleep(1);
		//SemUnlock( NULL );
	}	
}


int main(void)
{
	CreateChildProcess( semfn );
	char c;
	int sid;
	sem_t *	sem;


	printf("ipc start...");
	
	//SemDele(NULL);
	
	//sid = SemCreate(LOCK_PATH);
	//printf("sid:%d\n", sid );
	sem = PosixSemCreate( LOCK_PATH );	
	printf("sem=%p\ninput a char: ", sem );
	while ( (c=getchar())!='x' )
	{
		if (c=='p')
		{
			printf("post\n" );
			int ret=PosixSemPost( LOCK_PATH );
			printf("ret=%d\n", ret );
		}
// 		if (c=='l')
// 		{
// 			printf("SemLock\n" );
// 			SemLock( NULL );	
// 		}
// 		if (c=='d')
// 		{
// 		}
	}	
	printf("Delete sem\n" );
	PosixSemDele(LOCK_PATH);	
	return 1;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -