我同意可能有更好的方法来解决潜在问题的评论,例如用管道。但是,由于我有完全符合您描述的测试代码,因此我将与您分享。请注意,在运行此代码时,您应该始终在启动客户端之前启动服务器。
代码在共享内存之外创建了一对信号量。客户端使用REQUEST_SEM 向服务器发出数据可用的信号。服务器使用RESPONSE_SEM 来表明它已经完成了客户端的请求。
如果您决定更改共享内存的大小,则需要使用ipcrm 命令删除之前分配的共享内存。另一个有用的命令是ipcs,它列出了您创建的 IPC 对象。
最后一点。使用硬编码的key 是不好的。有关生成key 的更好方法,请参阅ftok 的文档。
服务器.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <errno.h>
#define REQUEST_SEM 0
#define RESPONSE_SEM 1
#define SEM_RA (SEM_R | SEM_A)
#define SEM_FLAGS (SEM_RA | (SEM_RA >> 3) | (SEM_RA >> 6))
#define MEM_RW (SHM_R | SHM_W)
#define MEM_FLAGS (MEM_RW | (MEM_RW >> 3) | (MEM_RW >> 6))
static void error( const char *msg )
{
perror( msg );
exit( 1 );
}
void waitForIt( int semid, int semnum )
{
struct sembuf operations = { semnum, -1, 0 };
if ( semop( semid, &operations, 1 ) < 0 )
error( __func__ );
}
void signalIt( int semid, int semnum )
{
struct sembuf operations = { semnum, 1, 0 };
if ( semop( semid, &operations, 1 ) < 0 )
error( __func__ );
}
int main( int argc, char *argv[] )
{
int i, semID, memID, good, bad;
char *memAddress;
if ( (semID = semget( 0x1001, 2, IPC_CREAT | SEM_FLAGS )) < 0 )
error( "Unable to create semaphores" );
if ( semctl( semID, REQUEST_SEM, SETVAL, 0 ) < 0 )
error( "Unable to initialize request semaphore" );
if ( semctl( semID, RESPONSE_SEM, SETVAL, 0 ) < 0 )
error( "Unable to initialize response semaphore" );
if ( (memID = shmget( 0x1001, 1024, IPC_CREAT | MEM_FLAGS )) < 0 )
error( "Unable to create shared memory" );
memAddress = shmat( memID, NULL, 0 );
if ( memAddress == NULL || memAddress == ((void *) -1) )
error( "Unable to attach shared memory" );
good = 0;
bad = 0;
for ( i = 0; i < 100; i++ )
{
waitForIt( semID, REQUEST_SEM );
if ( memAddress[0] == i )
good++;
else
bad++;
memAddress[0] = 0x55;
signalIt( semID, RESPONSE_SEM );
}
printf( "good=%d bad=%d\n", good, bad );
if ( shmdt( memAddress ) < 0 )
error( "Unable to detach shared memory" );
}
客户端.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <errno.h>
#define REQUEST_SEM 0
#define RESPONSE_SEM 1
static void error( const char *msg )
{
perror( msg );
exit( 1 );
}
void waitForIt( int semid, int semnum )
{
struct sembuf operations = { semnum, -1, 0 };
if ( semop( semid, &operations, 1 ) < 0 )
error( __func__ );
}
void signalIt( int semid, int semnum )
{
struct sembuf operations = { semnum, 1, 0 };
if ( semop( semid, &operations, 1 ) < 0 )
error( __func__ );
}
int main( void )
{
int i, semID, memID, good, bad;
char *memAddress;
if ( (semID = semget( 0x1001, 0, 0 )) < 0 )
error( "Unable to get semaphores" );
if ( (memID = shmget( 0x1001, 0, 0 )) < 0 )
error( "Unable to create shared memory" );
memAddress = shmat( memID, NULL, 0 );
if ( memAddress == NULL || memAddress == ((void *) -1) )
error( "Unable to attach shared memory" );
good = 0;
bad = 0;
for ( i = 0; i < 100; i++ )
{
memAddress[0] = i;
signalIt( semID, REQUEST_SEM );
waitForIt( semID, RESPONSE_SEM );
if ( memAddress[0] == 0x55 )
good++;
else
bad++;
}
printf( "good=%d bad=%d\n", good, bad );
if ( shmdt( memAddress ) < 0 )
error( "Unable to detach shared memory" );
}