linux中三个进程之间的共享内存同步

时间:2014-05-29 06:13:18

标签: c ipc embedded-linux semaphore shared-memory

在基于Linux的系统中,我有3个进程(A,B,C),共享一个共享内存。进程A使用进程内更新的实时值不断更新共享内存值。进程B读取共享内存并在终端中输出值(根据用户请求)。进程C是等待连接的服务器程序,并且在成功连接时,读取共享存储器值,然后将值发送到客户端。我试图用任何技术在3进程之间建立同步。当我想用信号量实现它时,主要关注的是进程A.进程A是一个永无止境的监视进程,并且它不会在任何时刻保持等待状态,因为它具有高优先级。进程B和C必须根据用户请求获取更新的共享内存值。我怎样才能做到这一点?示例代码如下。

处理A

int main()
{
    if ((shmid = shmget(1234/*key*/, sizeof(some struct), IPC_CREAT | 0777)) < 0) //Create the segment and set permissions
    perror("shmget");
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)// attaching
    perror("shmat");
    while(1)
    {
       //*************************************/
       //Monitoring routines******************/
       //*************************************/
       UpdateValuesToSharedMemory();  //function to update monitored values to shared memory
    }
}

流程B

int main()
{
    if ((shmid = shmget(1234/*key*/, sizeof(some struct), IPC_CREAT | 0777)) < 0) //Create the segment and set permissions
    perror("shmget");
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)// attaching
    perror("shmat");
    while(1)
    {
    do
    {
        scInString[ucLocal1]  = getchar();
        ucLocal1++;
        if(scInString[ucLocal1-1] == '\n')
        {
        break;
        }
    }while(ucLocal1<6);
    UpdateValuesFromSharedMemory();  //function to update monitored values to shared memory
    DisplayValues();  // Function to display the obtained values for shared memory      
    }
 }

流程C

int main()
{
    if ((shmid = shmget(1234/*key*/, sizeof(some struct), IPC_CREAT | 0777)) < 0) //Create the segment and set permissions
    perror("shmget");
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)// attaching
    perror("shmat");
    void *context = zmq_ctx_new ();
    responder = zmq_socket (context, ZMQ_REP);
    int rc = zmq_bind (responder, "tcp://*:5555");
    assert (rc == 0);
    while (1) {

        memset(buffer,'/0',2500);
        zmq_recv (responder, buffer, 2500, 0);      //Collect the request from the client
        UpdateValuesFromSharedMemory();  //function to update monitored values to shared memory

        json_object * jobjRcvd = json_tokener_parse(buffer);
        id = iGetCommandID(jobjRcvd);               //Find the command id

        cFunctionCommands[(id-1)](jobjRcvd);        //Call the function to prepare the reply with respect to the command
        zmq_send (responder, (char * )jsonmsg,strlen(jsonmsg), 0);//Reply to the client
       }
     }

1 个答案:

答案 0 :(得分:2)

有许多不同类型的Mutual exclusion对象可用于此。

对于您的用例,最简单的方法是使用标准的pthread互斥锁。在更新或读取数据块之前,每个进程都必须调用pthread_mutex_lock(),然后调用更新或读取操作,然后调用pthread_mutex_unlock()

有关如何创建类似互斥锁的说明,请参阅the man page for pthread_mutex_init()。特别是,由于您希望在进程之间进行同步,因此需要将互斥锁初始化为PTHREAD_PROCESS_SHARED。在the man page for pthread_mutexattr_init()中,在进程共享内存和同步一节中详细解释了这一点。

所有进程都需要可以访问互斥对象本身。由于您已有可用的共享内存段,因此可以选择重复使用它来存储互斥对象。在这种情况下,所有进程都需要知道在该块中查找的位置。您可以通过在代码示例中将互斥结构嵌入到some struct中来实现此目的。手册页中的代码示例为此目的打开一个单独的文件。

理论上,pthread_rwlock_t类型更符合要求(由用户oakad指出)(忽略任何潜在的CPU惩罚和其他实现细节),但我选择指向互斥锁,因为它有更多示例手册页中的代码。