gpt4 book ai didi

c - 如何协调两个进程之间的共享内存

转载 作者:太空宇宙 更新时间:2023-11-04 03:42:37 25 4
gpt4 key购买 nike

我有程序 A 和程序 B。程序 A 使用 shmget 创建一个队列,然后使用 shmat 将其存储到共享内存中。进程 B 启动,然后使用相同的 shmid 毫无问题地获取进程 A 创建的队列。进程 A(A 和 B 显然同时运行)然后运行一个修改队列中某个元素的方法。当程序 A 执行此操作时,指向该内存块的指针会给我一个段错误。我想可能是因为程序 B 现在有指向它的指针。我的问题是如何解决这个问题,以便程序 A 可以像程序 B 一样编辑和读取队列。我知道我需要某种锁,但不知道哪种锁最好或如何正确实现这。如果您可以提供一些示例代码来配合您的解释,那将有很大帮助。顺便说一句,我正在用 C 语言编写所有这些,进程 A 有 2 个键,一个到队列,另一个到一个数组,该数组保存从程序 A 分配到共享内存中的每个段的所有 shmids,程序 B 将使用它来检索该信息。

最佳答案

我同意可能有更好的方法来解决潜在问题的评论,例如与管道。但是,由于我有完全符合您描述的测试代码,因此我将与您分享。请注意,运行此代码时,您应该始终在启动客户端之前启动服务器。

除了共享内存之外,代码还创建了一对信号量。客户端使用 REQUEST_SEM 向服务器发出数据可用的信号。 RESPONSE_SEM 由服务器用来指示它已完成客户端的请求。

如果您决定更改共享内存的大小,则需要使用 ipcrm 命令删除之前分配的共享内存。另一个有用的命令是 ipcs,它列出了您创建的 IPC 对象。

最后一点。使用硬编码的 key 是不好的。请参阅 ftok 的文档以了解生成 key 的更好方法。

服务器.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" );
}

关于c - 如何协调两个进程之间的共享内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27336822/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com