📄 ipc.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 + -