헤더파일 : MultiProcessWithSemaphore.h

/*******************************************************************************
 * MultiProcessWithSemaphore.h
 *
 *
 *
 * IDENTIFICATION & REVISION
 *        $Id$
 *
 * NOTES
 *
 *
 ******************************************************************************/

/**
 * @file MultiProcessWithSemaphore.h
 * @brief 세마포어를 이용한 멀티 프로세스 큐
 *        헤더파일
 */


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <fcntl.h>
#include <time.h>


#define KEY_ID          9300
#define SIZE            8192
#define PROCESS_COUNT   10
#define DATA_MAX_COUNT  5

#define STL_SUCCESS     0
#define STL_FAILURE     1


#define STL_TRY_THROW( aExpression, aLabel )    \
    do                                          \
    {                                           \
        if( !(aExpression) )                    \
        {                                       \
            goto aLabel;                        \
        }                                       \
    } while( 0 )


#define STL_CATCH( aLabel )                     \
    goto STL_FINISH_LABEL;                      \
    aLabel:


#define STL_FINISH                              \
    STL_FINISH_LABEL:


typedef struct qNode
{
    int mData;

    struct qNode * mPrevNode;
    struct qNode * mNextNode;
} qNode;


typedef struct qQueue
{
    qNode * mFrontNode;
    qNode * mRearNode;
} qQueue;


typedef struct  qStruct
{
    qQueue  mQueue;
    void  * mShmAddr;
    int     mCount;
    sem_t   mSemaphore;
} qStruct;


void * qInitialize( qStruct * aStruct );


void * qEnqueue( qStruct * aStruct,
                 int       aProcessId );


void * qDequeue( qStruct * aStruct,
                 int       aProcessId );


소스파일 : MultiProcessWithSemaphore.c

/*******************************************************************************
 * MultiProcessWithSemaphore.c
 *
 *
 *
 * IDENTIFICATION & REVISION
 *        $Id$
 *
 * NOTES
 *
 *
 ******************************************************************************/

/**
 * @file MultiProcessWithSemaphore.c
 * @brief 세마포어를 이용한 멀티 프로세스 큐
 */


#include "MultiProcessWithSemaphore.h"


void * gShmAddrStart;


int main()
{
    pid_t  sProcessId[PROCESS_COUNT];

    void * sShmAddr   = NULL;


    int sShmId        = 0;
    int sIsDetachShm  = 0;
    int sIsRemoveShm  = 0;
    int sRepeatCount  = 0;
    int sStatus       = 0;

    int sStructSize   = 0;
    int sNodeSize     = 0;

    qStruct * sStruct = NULL;

    
    printf("+-----------------------------------+\n");
    printf("| [SYSTEM] :: program is Started... |\n");
    printf("+-----------------------------------+\n");


    /*
     * Initialize
     */


    /* 공유 메모리 생성 */
    sShmId = shmget( KEY_ID,
                     SIZE,
                     IPC_CREAT | 0666 );

    /* 공유 메모리 생성 실패 확인 */
    STL_TRY_THROW( sShmId != -1,
                   RAMP_ERROR_01 );

    printf("공유 메모리를 생성하였습니다.\n");


    /* 공유 메모리 attach */
    gShmAddrStart = shmat( sShmId,
                           (void *)0,
                           0 );

    /* attach 실패 확인 */
    STL_TRY_THROW( gShmAddrStart != (void *)-1,
                   RAMP_ERROR_02 );

    printf("공유 메모리를 attach 하였습니다.\n");

    
    /*
     * attach한 shared memory 주소로 구조체를 캐스팅
     *
     *  < SHARED MEMORY >
     *  +---------+-------------------------------------------------------
     *  | sStruct |
     *  +---------+-------------------------------------------------------
     *  ^
     *  gShmAddrStart
     *  
     */
    
    sStruct = (qStruct *)gShmAddrStart;

    /* 구조체 sStruct 초기화 */
    qInitialize( sStruct );

    /* 각 구조체들의 크기 */
    sStructSize = sizeof( qStruct );
    sNodeSize   = sizeof( qNode );

    /* ( shared memory 주소값 ) + ( 구조체 크기 )값을 구조체 멤버에 저장 */
    sStruct->mShmAddr = gShmAddrStart + sStructSize;

    
    /*
     * DO
     */


    for( sRepeatCount = 0; sRepeatCount < PROCESS_COUNT; sRepeatCount++ )
    {
        sProcessId[sRepeatCount] = fork();


        if( sProcessId[sRepeatCount] > 0 )
        {
            /* 부모 프로세스 */
            /* do nothing */
        }
        else if( sProcessId[sRepeatCount] == 0 )
        {
            /* 자식 프로세스 */
            /* 자식 프로세스 절반은 enqueue, 절반은 dequeue */
            if( sRepeatCount % 2 == 0 )
            {
                /* Enqueue */
                qEnqueue( sStruct, sRepeatCount );
            }
            else
            {
                /* Dequeue */
                qDequeue( sStruct, sRepeatCount );
            }
            
            exit( STL_SUCCESS );
        }
        else
        {
            /* fork 실패 */
            STL_TRY_THROW( STL_SUCCESS,
                           RAMP_ERROR_04 );
        }
    }



    /*
     * Finalize
     */


    /* 부모 프로세스의 wait 호출 */
    for( sRepeatCount = 0; sRepeatCount < PROCESS_COUNT; sRepeatCount++ )
    {
        sProcessId[sRepeatCount] = wait( &sStatus );
    }
    
    
    /* 세마포어 종료 */
    sem_destroy( &sStruct->mSemaphore );

    printf("세마포어를 종료하였습니다.\n");
    
    /* 공유 메모리 detach */
    sIsDetachShm = shmdt( gShmAddrStart );

    /* detach 실패 확인 */
    STL_TRY_THROW( sIsDetachShm != -1,
                   RAMP_ERROR_03 );
    
    printf("공유 메모리를 detach 하였습니다.\n");
    


    printf("+-----------------------------------+\n");
    printf("| [SYSTEM] :: program is Exited...  |\n");
    printf("+-----------------------------------+\n");
    

    
    return STL_SUCCESS;

    
    STL_CATCH( RAMP_ERROR_01 )
    {
        printf("[ERROR-01] :: cannot get shared memory which key '%d'.\n", KEY_ID );
    }

    STL_CATCH( RAMP_ERROR_02 )
    {
        printf("[ERROR-02] :: cannot attach shared memory which key '%d'.\n", KEY_ID );
    }

    STL_CATCH( RAMP_ERROR_03 )
    {
        printf("[ERROR-03] :: cannot detach shared memory which key '%d'.\n", KEY_ID );
    }

    STL_CATCH( RAMP_ERROR_04 )
    {
        printf("[ERROR-04] :: cannot create child process.\n");
    }

    
    STL_FINISH;
    

    return STL_FAILURE;
}


void * qInitialize( qStruct * aStruct )
{
    aStruct->mQueue.mFrontNode = NULL;
    aStruct->mQueue.mRearNode  = NULL;
    
    aStruct->mShmAddr = NULL;
    aStruct->mCount   = 0;

    /* 세마포어 초기화 */
    sem_init( &aStruct->mSemaphore,
              1,
              1 );
}


void * qEnqueue( qStruct * aStruct,
                 int       aProcessId )
{
    int     sRepeatCount = 0;
    int     sNodeSize    = 0;

    qNode * sNewNode     = NULL;

    sNodeSize = sizeof( qNode );

    /* rand() */
    srand( aProcessId );

    while( sRepeatCount < DATA_MAX_COUNT )
    {
        /* semaphore lock */
        sem_wait( &aStruct->mSemaphore );

        if( aStruct->mCount >= PROCESS_COUNT )
        {
            /* printf("queue is full!\n"); */
        }
        
        else
        {
            /*
             *  < SHARED MEMORY >
             *  +---------+----------+--------------------------------------------
             *  | sStruct | sNewNode |                   
             *  +---------+----------+--------------------------------------------
             *            ^
             *            mShmAddr
             *  
             */
            
            sNewNode = (qNode *)aStruct->mShmAddr;
            aStruct->mShmAddr += sNodeSize;


            /* 두 자리 임의의 수를 sNewNode의 mData에 저장 */
            sNewNode->mData = rand()%90 + 10;
            sNewNode->mNextNode = NULL;
        
            if( aStruct->mCount == 0 )
            {
                aStruct->mQueue.mFrontNode = sNewNode;
                sNewNode->mPrevNode = NULL;
            }
            else
            {
                aStruct->mQueue.mRearNode->mNextNode = sNewNode;
                sNewNode->mPrevNode = aStruct->mQueue.mRearNode;
            }

            aStruct->mQueue.mRearNode = sNewNode;
            aStruct->mCount++;

            printf("[#%3d][ENQUEUE_DATA] : %d  QUEUE STATUS [ %2d/%d ]\n",
                   aProcessId,
                   aStruct->mQueue.mRearNode->mData,
                   aStruct->mCount,
                   PROCESS_COUNT );

            sRepeatCount++;
        }

        /* semaphore unlock */
        sem_post( &aStruct->mSemaphore );
        usleep(50);
    }
}


void * qDequeue( qStruct * aStruct,
                 int       aProcessId )
{
    int    sRepeatCount = 0;
    int    sOutputData  = 0;
    int    sStructSize  = 0;
    int    sNodeSize    = 0;
    
    void * sShmAddr     = NULL;

    sStructSize = sizeof( qStruct );
    sNodeSize   = sizeof( qNode );
    

    while( sRepeatCount < DATA_MAX_COUNT )
    {
        sem_wait( &aStruct->mSemaphore );

        if( aStruct->mCount == 0 )
        {
            /* printf("queue is empty!\n"); */
        }

        else
        {
            sOutputData = aStruct->mQueue.mFrontNode->mData;

            if( aStruct->mCount == 1 )
            {
                aStruct->mQueue.mFrontNode = NULL;
                aStruct->mQueue.mRearNode  = NULL;
                aStruct->mCount            = 0;
            }

            else
            {
                aStruct->mQueue.mFrontNode = aStruct->mQueue.mFrontNode->mNextNode;
                aStruct->mQueue.mFrontNode->mPrevNode = NULL;
                aStruct->mCount--;
            }

            printf("[#%3d][DEQUEUE_DATA] : %d  QUEUE STATUS [ %2d/%d ]\n",
                   aProcessId,
                   sOutputData,
                   aStruct->mCount,
                   PROCESS_COUNT );

            sRepeatCount++;
        }

        sem_post( &aStruct->mSemaphore );
        usleep(50);
    }
}


공부/코딩연습 등의 이유로 얼마든지 퍼가셔도 좋습니다.


하지만 라인마다 의미를 파악하지 않고 무작정 복사 붙여넣기는

아무것도 남지 않습니다.


또한 댓글로 궁금하신 라인 등 얼마든지 물어보시면 

바로바로 대답해드리겠습니다 :)


공부를 게을리하지 맙시다! 


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

헤더파일 : MultiThreadWithSignal.h

/*******************************************************************************
 * MultiThreadWithSignal.h
 *
 *
 *
 * IDENTIFICATION & REVISION
 *        $Id$
 *
 * NOTES
 *
 *
 ******************************************************************************/

/**
 * @file MultiThreadWithSignal.h
 * @brief 다중 연결 리스트( Doubly Linked List ) 큐
 *        Enqueue와 Dequeue를 스레드를 통해 진행
 *        헤더파일
 */


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


#define THREAD_COUNT    100
#define DATA_MAX_COUNT  2000


/* 큐를 이루는 노드 구조체 */
typedef struct qNode
{
    int             mData;             /* Data */
    int             mEnqueueThreadId;  /* 데이터를 준 스레드 ID */
    
    struct qNode  * mPrevNode;         /* 이전 Node */
    struct qNode  * mNextNode;         /* 다음 Node */
} qNode;


/* 큐 구조체 */
typedef struct qQueue
{
    qNode  * mFrontNode;      /* Dequeue */
    qNode  * mRearNode;       /* Enqueue */
    
    int      mCount;          /* 노드 갯수 */
} qQueue;


/* 스레드 생성 시 인자로 넘겨주는 구조체 */
typedef struct qArgPthread
{
    qQueue  * mQueue;         /* Queue */
    int       mThreadId;      /* 스레드 ID */
} qArgPthread;


/* Initialize Queue */
void  qInitQueue( qQueue * aQueue );


/* Enqueue */
void  * qEnqueue( void * aArgPthread );


/* Dequeue */
void  * qDequeue( void * aArgPthread );


소스파일 : MultiThreadWithSignal.c

/*******************************************************************************
 * MultiThreadWithSignal.c
 *
 * Copyright (c) 2011, SUNJESOFT Inc.
 *
 *
 * IDENTIFICATION & REVISION
 *        $Id$
 *
 * NOTES
 *
 *
 ******************************************************************************/

/**
 * @file MultiThreadWithSignal.c
 * @brief 다중 연결 리스트( Doubly Linked List ) 큐
 *        Enqueue와 Dequeue를 스레드를 통해 진행
 *        Enqueue 스레드가 enqueue 이후 signal을 전송,
 *        Dequeue 스레드가 signal을 받고 dequeue를 수행
 *        다시 Enqueue 스레드에게 작업을 마친 flag를 넘긴다.
 */


#include "MultiThreadWithSignal.h"


/* Global Mutex & Condition Variable */
pthread_mutex_t  gMutexForThread;
pthread_mutex_t  gMutexForEnqDeq[THREAD_COUNT];

pthread_cond_t   gCondition[THREAD_COUNT];


/* Flag Variables */
int  gMainFlag;
int  gFlagForThread[THREAD_COUNT];
int  gFlagForEnqDeq[THREAD_COUNT];


int main()
{
    pthread_t      sEnqueueThread[THREAD_COUNT];      /* THREAD_COUNT 만큼의 Enqueue 스레드 선언 */
    pthread_t      sDequeueThread[THREAD_COUNT];      /* THREAD_COUNT 만큼의 Dequeue 스레드 선언 */
    
    qArgPthread  * sArgEnqueueThread[THREAD_COUNT];   /* THREAD_COUNT 만큼의 인자로 넘겨줄 구조체 */
    qArgPthread  * sArgDequeueThread[THREAD_COUNT];   /* THREAD_COUNT 만큼의 인자로 넘겨줄 구조체 */

    qQueue       * sQueue              = NULL;

    int            sIsCreatedThread    = 0;           /* 스레드가 Create되었는지 여부를 알기 위한 변수 */
    int            sIsJoinedThread     = 0;           /* 스레드가 Join되었는지 여부를 알기 위한 변수 */
    int            sReturnValue        = 0;           /* 스레드가 Join 수행 시 반환하는 값 */
    int            sCountThread        = 0;           /* 스레드 개수, 각종 for문의 정수형 변수 */
    int            sDoubleThreadCount  = 0;

    sQueue  = (qQueue *)malloc( sizeof( qQueue ) );
    
    sDoubleThreadCount = THREAD_COUNT * 2;            /* THREAD_COUNT의 두배 */

    
    /*
     * Initialize
     */

    pthread_mutex_init( &gMutexForThread, NULL );

    for( sCountThread = 0; sCountThread < THREAD_COUNT; sCountThread++ )
    {
        /* Mutex */        
        pthread_mutex_init( &gMutexForEnqDeq[sCountThread], NULL );

        /* Condition Value */
        pthread_cond_init( &gCondition[sCountThread], NULL );

        /* Flags */
        gFlagForThread[sCountThread] = 0;
        gFlagForEnqDeq[sCountThread] = 0;
    }

    gMainFlag = 0;            /* Flag */
    
    qInitQueue( sQueue );     /* 큐 sQueue 초기화 */

    
    /* 스레드 Mutex Lock */
    pthread_mutex_lock( &gMutexForThread );

    
    /*
     * 스레드 Create
     */


    /* Enqueue 스레드 */
    for( sCountThread = 0; sCountThread < THREAD_COUNT; sCountThread++ )
    {
        sArgEnqueueThread[sCountThread] = (qArgPthread *)malloc( sizeof( qArgPthread ) );

        /* 인자의 스레드 ID는 0, 1, ..., n */
        sArgEnqueueThread[sCountThread]->mQueue     = sQueue;
        sArgEnqueueThread[sCountThread]->mThreadId  = sCountThread;
        
        sIsCreatedThread = pthread_create( &sEnqueueThread[sCountThread],
                                           NULL,
                                           &qEnqueue,
                                           (void *)sArgEnqueueThread[sCountThread] );

        if( sIsCreatedThread != 0 )
        {
            printf("[ERROR-001] :: cannot create thread.\n");
        }
    }
    
    /* Dequeue 스레드 */
    for( sCountThread = 0; sCountThread < THREAD_COUNT; sCountThread++ )
    {
        sArgDequeueThread[sCountThread] = (qArgPthread *)malloc( sizeof( qArgPthread ) );

        /* 인자의 스레드 ID는 0, 1, ..., n */
        sArgDequeueThread[sCountThread]->mQueue     = sQueue;
        sArgDequeueThread[sCountThread]->mThreadId  = sCountThread;
        
        sIsCreatedThread = pthread_create( &sDequeueThread[sCountThread],
                                           NULL,
                                           &qDequeue,
                                           (void *)sArgDequeueThread[sCountThread] );

        if( sIsCreatedThread != 0 )
        {
            printf("[ERROR-001] :: cannot create thread.\n");
        }
    }

    /* 모든 스레드 생성 후 플래그 값 확인 */
    while( gMainFlag < sDoubleThreadCount )
    {
        gMainFlag = 0;
        for( sCountThread = 0; sCountThread < THREAD_COUNT; sCountThread++ )
        {
            gMainFlag += gFlagForThread[sCountThread];
        }
        sleep(0);
    }

    /* 스레드 Mutex Unlock */
    pthread_mutex_unlock( &gMutexForThread );
    
    /*
     * 스레드 Join
     */

    for( sCountThread = 0; sCountThread < THREAD_COUNT; sCountThread++ )
    {
        /* Enqueue 스레드 */
        sIsJoinedThread = pthread_join( sEnqueueThread[sCountThread],
                                        (void **)&sReturnValue );

        if( sIsJoinedThread != 0 )
        {
            printf("[ERROR-002] :: cannot join enqueue thread.\n");
        }

        
        /* Dequeue 스레드 */
        sIsJoinedThread = pthread_join( sDequeueThread[sCountThread],
                                        (void **)&sReturnValue );

        if( sIsJoinedThread != 0 )
        {
            printf("[ERROR-002] :: cannot join dequeue thread.\n");
        }
        
    }

    printf("\n+-----------------------------------+");
    printf("\n| [SYSTEM] :: program is Exited.... |\n");
    printf("+-----------------------------------+\n\n");
    
    return 0;
}



/* Initialize Queue */
void qInitQueue( qQueue * aQueue )
{
    aQueue->mFrontNode  = NULL;
    aQueue->mRearNode   = NULL;
    aQueue->mCount      = 0;

    printf("\n+-----------------------------------+");
    printf("\n| [SYSTEM] :: queue is Initialized. |\n");
    printf("+-----------------------------------+\n\n");

}



/* Enqueue */
void  * qEnqueue( void * aArgPthread )
{
    qArgPthread * sArgPthread   = NULL;
    qQueue      * sQueue        = NULL;
    qNode       * sNewNode      = NULL;

    int           sInputData    = 0;
    int           sRepeatCount  = 0;
    int           sThreadId     = 0;
    /* int           sMaxBuff      = 0; */

    sArgPthread = (qArgPthread *)aArgPthread;

    sQueue      = sArgPthread->mQueue;
    sThreadId   = sArgPthread->mThreadId;

    /* sMaxBuff    = DATA_MAX_COUNT * 2; */

    printf("[#%3d][ENQUEUE_THREAD] is ready.\n", sThreadId );
    gFlagForThread[sThreadId] += 1;
    
    while( sRepeatCount < DATA_MAX_COUNT )
    {
        /* Dequeue 스레드의 준비를 기다린다. */
        while( gFlagForEnqDeq[sThreadId] == 0 )
        {
            sleep(0);
        }
        
        /* 스레드 Mutex Lock */
        pthread_mutex_lock( &gMutexForThread );

        sNewNode = (qNode *)malloc( sizeof( qNode ) );
            
        if( sQueue->mCount >= THREAD_COUNT /* sMaxBuff */ )
        {
            /* printf("[THREAD_%d]\n[ERROR-003] :: queue is full. [ %d/%d ]\n\n", */
            /*        sThreadId, */
            /*        DATA_MAX_COUNT, */
            /*        DATA_MAX_COUNT ); */
        }
        else
        {
            sInputData                  = rand() % 90 + 10; /* 임의의 데이터 값을 두자리 수로 고정 */
            sNewNode->mData             = sInputData;
            sNewNode->mNextNode         = NULL;
            sNewNode->mEnqueueThreadId  = sThreadId;

            printf("[#%3d][ENQUEUE_THREAD] Enqueue DATA : %d( %d/%d ) QUEUE STATUS : [ %d/%d ]\n",
                   sThreadId,
                   sInputData,
                   sRepeatCount+1,
                   DATA_MAX_COUNT,
                   sQueue->mCount+1,
                   THREAD_COUNT /* sMaxBuff */ );

            if( sQueue->mCount == 0 )
            {
                sQueue->mFrontNode   = sNewNode;
                sNewNode->mPrevNode  = NULL;
            }
            else
            {
                sQueue->mRearNode->mNextNode  = sNewNode;
                sNewNode->mPrevNode           = sQueue->mRearNode;
            }

            sQueue->mRearNode  = sNewNode;
            sQueue->mCount++;

            sRepeatCount++;
        }

        /* 스레드 Mutex Unlock */
        pthread_mutex_unlock( &gMutexForThread );

        /* Enqueue Mutex Lock */
        pthread_mutex_lock( &gMutexForEnqDeq[sThreadId] );

        gFlagForEnqDeq[sThreadId] = 0; /* 0으로 다시 초기화 */
        
        /* Dequeue 스레드에게 시그널 */
        pthread_cond_signal( &gCondition[sThreadId] );

        /* Enqueue Mutex Unlock */
        pthread_mutex_unlock( &gMutexForEnqDeq[sThreadId] );

        /* if( sRepeatCount%5 == 0 ) */
        /* { */
        usleep(50);
        /* } */
    }
}





/* Dequeue */
void  * qDequeue( void * aArgPthread )
{
    qArgPthread * sArgPthread   = NULL;
    qQueue      * sQueue        = NULL;

    int       sOutputData       = 0;
    int       sRepeatCount      = 0;
    int       sThreadId         = 0;
    int       sEnqueueThreadId  = 0;
    /* int       sMaxBuff          = 0; */

    sArgPthread = (qArgPthread *)aArgPthread;
    
    sQueue     = sArgPthread->mQueue;
    sThreadId  = sArgPthread->mThreadId;

    /* sMaxBuff   = DATA_MAX_COUNT * 2; */

    printf("[#%3d][DEQUEUE_THREAD] is ready.\n", sThreadId );
    gFlagForThread[sThreadId] += 1;

    while( sRepeatCount < DATA_MAX_COUNT )
    {
        /* Mutex Lock */
        pthread_mutex_lock( &gMutexForEnqDeq[sThreadId] );

        /* Enqueue 스레드에게 준비가 되었음을 알림 */
        gFlagForEnqDeq[sThreadId] = 1;

        /* Enqueue 까지 기다린다. */
        pthread_cond_wait( &gCondition[sThreadId], &gMutexForEnqDeq[sThreadId] );

        /* Mutex Unlock */
        pthread_mutex_unlock( &gMutexForEnqDeq[sThreadId] );
        
        /* 스레드 Mutex Lock */
        pthread_mutex_lock( &gMutexForThread );

        if( sQueue->mCount == 0 )
        {
            /* printf("[THREAD_%d]\n[ERROR-004] :: queue is empty. [ 0/%d ]\n\n", */
            /*        sThreadId, */
            /*        DATA_MAX_COUNT ); */
        }
        else
        {
            sOutputData       = sQueue->mFrontNode->mData;
            sEnqueueThreadId  = sQueue->mFrontNode->mEnqueueThreadId;

            printf("[#%3d][DEQUEUE_THREAD] Dequeue DATA : %d( %d/%d ) QUEUE STATUS : [ %d/%d ] data by [#%3d][ENQUEUE_THREAD]\n",
                   sThreadId,
                   sOutputData,
                   sRepeatCount+1,
                   DATA_MAX_COUNT,
                   sQueue->mCount-1,
                   THREAD_COUNT /* sMaxBuff */,
                   sEnqueueThreadId );

            if( sQueue->mCount == 1 )
            {
                free( sQueue->mFrontNode );
                sQueue->mFrontNode  = NULL;
                sQueue->mRearNode   = NULL;
                sQueue->mCount      = 0;
            }
            else
            {
                sQueue->mFrontNode = sQueue->mFrontNode->mNextNode;
                free( sQueue->mFrontNode->mPrevNode );
                sQueue->mFrontNode->mPrevNode = NULL;
                sQueue->mCount--;
            }

            sRepeatCount++;
        }

        /* 스레드 Mutex Unlock */
        pthread_mutex_unlock( &gMutexForThread );

        /* if( sRepeatCount%5 == 0 ) */
        /* { */
            usleep(50);
        /* } */

    }

}



공부/코딩연습 등의 이유로 얼마든지 퍼가셔도 좋습니다.


하지만 라인마다 의미를 파악하지 않고 무작정 복사 붙여넣기는

아무것도 남지 않습니다.


또한 댓글로 궁금하신 라인 등 얼마든지 물어보시면 

바로바로 대답해드리겠습니다 :)


공부를 게을리하지 맙시다! 


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

Array based QUEUE

What is it?

  • Array 기반의 Queue
  • 기본적으로 Enqueue (Insert)Dequeue (Delete) 연산이 가능한 FIFO (First-In, First-Out) 자료구조이다.
  • 너무 간단한 코드라 자세한 설명은 생략한다.
  • FIFO란? 먼저 들어온 자료가 먼저 나가는 것으로, 줄을 서다가 입장하는 것을 연상하면 된다.


CODE

/************************************************** * Array 기반의 Queue ***************************** * ************************************ q.c ******** * *************************************************/ #include <stdio.h> #define MAX_BUFF 10 /* Data for Queue */ typedef struct qData { int qkey; // 키 char qvalue; // 값 } qData; struct qData queue[MAX_BUFF]; /* Information for Queue */ int qTail; /* 삽입되는 부분에 대한 정보 */ int qNum; /* 입력받은 총 데이터 수 */ int countDe; /* 현재 데이터의 개수를 위한 디큐 횟수 */



/* * Dequeue시 Head의 데이터를 삭제하는 * 동시에 모든 데이터를 한칸씩 앞으로 * 옮긺으로써 Head를 따로 선언하지 않음. */

/* Queue Initiation */ void qInit() { qTail = 1; qNum = 0; countDe = 0; for(int i=0; i<MAX_BUFF; i++) { queue[i].qkey = '\0'; queue[i].qvalue = '\0'; } } /* Queue Print for Enqueue */ void qPrintEn() { int i; /* variable for 'for clause' */ printf("\n Current Queue's status is :\n\n"); printf(" KEY VALUE\n"); for( i = qTail-1 ; /*qTail-1*/ i >= 0; /*qHead-1*/ i--) { printf(" %d %s\n", queue[i].qkey, &queue[i].qvalue); } printf("\n"); printf("The number of data which you into : %d\n", qNum); printf("The number of data which current exist : %d\n\n", qNum-countDe); } /* Queue Print for Dequeue */ void qPrintDe() { int i; /* variable for 'for clause' */ printf("\n Current Queue's status is :\n\n"); printf(" KEY VALUE\n"); for( i = qTail-3 ; /* qTail-2 */ i>=0; /* qHead */ i--) { printf(" %d %s\n", queue[i].qkey, &queue[i].qvalue); } printf("\n"); printf("The number of data which you into : %d\n", qNum); printf("The number of data which current exist : %d\n\n", qNum-countDe); } /* Queue Insert the data 'val' */ void enQ(char val) { if ( qTail >= 11 ) { /* If the Queue is full */ printf("\nerror::queue overflow.\n"); } else { qNum++; queue[qTail-1].qkey = qNum; queue[qTail-1].qvalue = val; qPrintEn(); qTail++; } } /* Queue Delete the data from head */ void deQ() { if( qTail == 1 ) { /* If the Queue is empty */ printf("\nerror::queue is already empty.\n"); } else { countDe++; printf("Deleted data : %s\n", &queue[0].qvalue); queue[0].qkey = '\0'; queue[0].qvalue = '\0'; for(int i=1; i<qTail; i++) { queue[i-1].qkey = queue[i].qkey; queue[i-1].qvalue = queue[i].qvalue; } qPrintDe(); qTail--; } } /* MAIN FUNCTION */ int main() { qInit(); printf("\n\nIt's an array based Queue.\n\n"); int menu; char push; while(menu!=3) { printf("\nYou make a choice to menu.\n\n"); printf("Press '0' If you wanna Initiation.\n"); printf("Press '1' If you wanna Enqueue.\n"); printf("Press '2' Ifyou wanna Dequeue.\n"); printf("Press '3' If you wanna exit.\n\n"); printf(" PRESS : "); scanf("%d", &menu); switch(menu) { case 0: printf("You pressed '0' to Initiation.\n"); printf("So, the stack is cleared.\n"); qInit(); qPrintDe(); break; case 1: printf("You pressed '1' to Enqueue.\n"); printf("Press the character which you want to Enqueue. : "); scanf( "%s", &push ); enQ(push); break; case 2: printf("You pressed '2' to Dequeue.\n"); deQ(); break; case 3: printf("Exit......\n\n"); break; default: printf("It's wrong number. press again.\n\n"); break; } // switch } // while return 0; }


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,