SW 개발

Linux Application Shared Memory 관련 예제코드 : 동기화

. . . 2013. 12. 17. 15:50
반응형

일단 가장기본적으로 ipc : shared Memory 를 사용하는 방법을 테스트한다.

1. 기본개념

http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/system_programing/Book_LSP/ch08_IPC#s-2.4

위의 사이트에 가장 잘 설명되어있는 듯...

2. 기본예제 : mutex 를 이용한 예제

기본적으로 shm 가 동기화가 되는지 안되는지 자세한 내용이 나와있지 않아서 아예 mutex 를 걸기로 하고 테스트하였다.

공유된 메모리에 mutex context 를 초기화 하여 넣은다음 동일한 context 로 동기화가 가능했다.

아래의 문제점? 은 write side 에서... sleep() 을 오래잡고있으면 read에서 mutex 를 걸고 풀다가 write side 에서 fatal 이 발생하는데.. 이유는 잘모르겠음;;;

Write Side...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>     // sleep()
#include <sys/ipc.h>
#include <sys/shm.h>

#include <pthread.h>
#include <semaphore.h>

typedef struct shLock
{
    pthread_mutex_t mutex;
    pthread_mutexattr_t mutexAttr;
    char buffer[100];
}shLock;


void main()
{
    int shmid;
    key_t key = 5678;
    shLock* lockptr;
    int i=1;

    char d[] = "Start Test....";

    if ((shmid = shmget(key, sizeof(shLock), IPC_CREAT | 0666)) < 0) 
    {
        printf("[writeop] error : cannot creat shmrn");
    }

    if ((lockptr = (shLock*)shmat(shmid, NULL, 0)) == (shLock *) -1) 
    {
        printf("[writeop] error : failed attach memoryrn");
    }

    memset( lockptr->buffer,0,sizeof( lockptr->buffer) );

    memcpy( lockptr->buffer,d,strlen( d ) );

    if( pthread_mutexattr_init( &lockptr->mutexAttr ) == 0 )
    {
        printf("[writeop] success : shared mutex attr intializedrn");

    }

    if( pthread_mutexattr_setpshared( &lockptr->mutexAttr,PTHREAD_PROCESS_SHARED) == 0 )
    {
        printf("[writeop] success : shared mutexattribute setrn");
    }

    if( pthread_mutex_init( &lockptr->mutex, &lockptr->mutexAttr) == 0 )
    {
        printf("[writeop] success : shared mutex intializedrn");
    }

    while(1)
    {
        char buff[128]={0,};
        int waitsec=3;

        sleep(1);

        sprintf(buff,"write test string is [%d]rn", i);
        if( pthread_mutex_lock( &lockptr->mutex ) == 0 )
        {
            memcpy( lockptr->buffer, buff ,strlen( buff ) );

            /*
            while(waitsec--)
            {
                printf("[writeop] wait write...[%d]rn",waitsec);
                usleep(100);
            }
            */
        }
        pthread_mutex_unlock( &lockptr->mutex ) ;
        printf("[writeop] run...rn");
        i++;

    }
}

Read Side...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>     // sleep()
#include <sys/ipc.h>
#include <sys/shm.h>

#include <pthread.h>
#include <semaphore.h>

typedef struct shLock
{
    pthread_mutex_t mutex;
    pthread_mutexattr_t mutexAttr;
    char buffer[100];
}shLock;


void main()
{
    int shmid;
    key_t key = 5678;
    shLock* lockptr;

    if ((shmid = shmget(key, sizeof(shLock), IPC_CREAT | 0666)) < 0) 
    {
        printf("[readop] error : cannot creat shmrn");
    }

    if ((lockptr = (shLock*)shmat(shmid, NULL, 0)) == (shLock *) -1) 
    {
        printf("[readop] error : failed attach memoryrn");
    }



    while(1)
    {
        usleep(5000);


        if( pthread_mutex_lock( &lockptr->mutex ) == 0 )
        {
            printf("[readop] shLock->buffer is [%s]rn",lockptr->buffer);
        }
        printf("[readop] run...rn");
        pthread_mutex_unlock( &lockptr->mutex );

    }
}

3. 기본예제 : shm 내의 자체 lock / unlock 기능 사용

http://www.cs.cf.ac.uk/Dave/C/node27.html

위의 사이트에 SHM_LOCK 을 이용하여 Memory 를 Lock 할수있다고 되어있어서 동기화 기능으로 사용가능한지 살펴보았다;;;

shmctl() 함수를 이용하는 방법

  • 결론 : 의미없음!!

http://linux.die.net/man/2/shmctl

  • SHM_LOCK (Linux-specific)
    • Prevent swapping of the shared memory segment. The caller must fault in any pages that are required to be present after locking is enabled. If a segment has been locked, then the (nonstandard) SHM_LOCKED flag of the shm_perm.mode field in the associated data structure retrieved by IPC_STAT will be set.
  • SHM_UNLOCK (Linux-specific)
    • Unlock the segment, allowing it to be swapped out.
    • In kernels before 2.6.10, only a privileged process could employ SHM_LOCK and SHM_UNLOCK. Since kernel 2.6.10, an unprivileged process can employ these operations if its effective UID matches the owner or creator UID of the segment, and (for SHM_LOCK) the amount of memory to be locked falls within the RLIMIT_MEMLOCK resource limit (see setrlimit(2)).

여기서 말하는 Lock 이란 Memory 에 상주시켜서 Swap 으로 내리지 않게 하는 기능일뿐, 동기화와는 아무런 상관이 없는듯하다;;

실제로 코드로 테스트해보니, Lock 기능과는 아무런 의미가 없었다.!!

반응형