본문 바로가기

리눅스 프로그래밍

[운영체제] 세마포어를 사용해 프로세스통신 구현해보기_Client방식

// 클라이언트 방식. 클라이언트에서 버퍼에 모은 후 프로세스 통신 시간 측정

// 공유메모리를 사용했음.

// server.c

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#include <errno.h>

#include <sys/time.h>


#define fifoSize 1024

#define serverSize 32768

union semun{

        int val;

        struct  semid_ds *buf;

        unsigned short *array;

};


int initsem(key_t semkey){

        union semun semunarg;

        int status =0, semid;


        semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | 0644);

        if(semid == -1){

                if(errno == EEXIST){

                        semid = semget(semkey, 1, 0);

                }

        }

        else{

                semunarg.val = 1;

                status =  semctl(semid, 0, SETVAL, semunarg);

        }


        if(semid == -1 || status == -1){

                perror("initsem");

                return(-1);

        }


        return semid;

}


int semlock(int semid){

        struct sembuf buf;


        buf.sem_num = 0;

        buf.sem_op = -1;

        buf.sem_flg = SEM_UNDO;

        if(semop(semid, &buf, 1) == -1){

                perror("semlock failed");

                exit(1);

        }

        return 0;

}


int semunlock(int semid){

        struct sembuf buf;


        buf.sem_num = 0;

        buf.sem_op = 1;

        buf.sem_flg = SEM_UNDO;

        if(semop(semid, &buf, 1) == -1){

                perror("semunlock failed");

                exit(1);

        }

        return 0;

}


void sort(int *buf, int bufoff){

        int i,j,temp;

        for(i=0; i<bufoff; i++){

                for(j=0; j<bufoff; j++){

                        if(buf[i] <= buf[j]){

                                temp = buf[i];

                                buf[i] = buf[j];

                                buf[j] = temp;

                        }

                }

        }

}


int main(void) {

        int pd[8], n, i, j, l, k, bufoff=0;

        int buf[serverSize];

        int rbuf[fifoSize];

        char computeFifo[20] = "./computeNode";

        pid_t pid;


        struct timeval start, end, gap, total;

        int fd;


        memset(&start, 0, sizeof(start));

        memset(&end, 0, sizeof(end));

        memset(&gap, 0, sizeof(gap));

        memset(&gap, 0, sizeof(total));


        for(i=0; i<8; i++){

                computeFifo[13] = '1'+i;

                if (mkfifo(computeFifo, 0666) == -1){

                    perror("mkfifo");

                    exit(1);

                 }

        }


        for(i=0; i<8; i++){

                computeFifo[13] = '1'+i;

                if ((pd[i] = open(computeFifo, O_RDONLY)) == -1){

                    perror("open");

                    exit(1);

                }

        }


        int temp;

        if((pid = fork())==0){

                int semid;

                if((semid = initsem(1)) < 0) exit(1);

                if((fd = open("serverDataChild.dat", O_CREAT | O_WRONLY | O_TRUNC, 0600)) == -1){

                        perror("fopen");

                        exit(1);

                }


                //gettimeofday(&start, NULL);

                for(i=0; i<8; i++){

                        for(l=0; l<serverSize/fifoSize; l++){


                                semlock(semid);

                                for(j=0; j<128; j++){

                                        gettimeofday(&start, NULL);

                                        if((n=read(pd[i],&temp,sizeof(int)))>0){

                                                gettimeofday(&end, NULL);

                                                gap.tv_sec = end.tv_sec-start.tv_sec;

                                                gap.tv_usec = end.tv_usec - start.tv_usec;

                                                if(gap.tv_usec >0){

                                                        total.tv_usec += gap.tv_usec;

                                               }

                                                total.tv_sec += gap.tv_sec;


                                                buf[bufoff] = temp;

                                                bufoff++;

                                        }

                                        else {

                                                semunlock(semid);

                                                break;

                                        }

                                }

                                semunlock(semid);

                        }

                }

                printf("\ncommunication time :%ld 초 %ld\n ",total.tv_sec, total.tv_usec);


                /*if(gap.tv_usec >0){

                        total.tv_usec += gap.tv_usec;

                }

                total.tv_sec += gap.tv_sec;*/


                semlock(semid);

                //printf("Child Server:");


                memset(&start, 0, sizeof(start));

                memset(&end, 0, sizeof(end));

                memset(&gap, 0, sizeof(gap));


                //gettimeofday(&start, NULL);

                sort(buf, bufoff);

                //gettimeofday(&end, NULL);


                //gap.tv_sec = end.tv_sec - start.tv_sec;

                //gap.tv_usec = end.tv_usec- start.tv_usec;


                //if(gap.tv_usec >0){

                //      total.tv_usec += gap.tv_usec;

                //}

                //total.tv_sec += gap.tv_sec;


                memset(&start, 0, sizeof(start));

                memset(&end, 0, sizeof(end));

                memset(&gap, 0, sizeof(gap));


                gettimeofday(&start,NULL);

                for(i=0; i<bufoff; i++){

                        write(fd,&buf[i],sizeof(buf[i]));

                }

                gettimeofday(&end, NULL);


                gap.tv_usec = end.tv_usec-start.tv_usec;

                gap.tv_sec = end.tv_sec - start.tv_sec;

                printf("write time: %ld\n", gap.tv_usec);

                if(gap.tv_usec >0){

                        total.tv_usec += gap.tv_usec;

                }

                total.tv_sec += gap.tv_sec;


                printf("child server total time :%ld초 %ld us\n",total.tv_sec, total.tv_usec);

                semunlock(semid);

                exit(1);

        }

        else if(pid ==-1){ perror("fork");exit(1);}

        else{

                int semid;

                if((semid = initsem(1)) < 0) exit(1);


                if((fd = open("serverDataParent.dat", O_CREAT | O_WRONLY | O_TRUNC, 0600)) == -1){

                        perror("fopen");

                        exit(1);

                }

                for(i=0; i<8; i++){

                        for(l=0; l<serverSize/fifoSize; l++){

                                semlock(semid);

                                for(j=0; j<128; j++){

                                        if((n=read(pd[i],&temp,sizeof(int)))>0){

                                                buf[bufoff] = temp;

                                                bufoff++;

                                        }

                                        else{

                                                semunlock(semid);

                                                break;

                                        }

                                }

                                semunlock(semid);

                        }

                }

                semlock(semid);

                printf("Parent Server: ");

                sort(buf, bufoff);


                for(i=0; i<bufoff; i++){

                        write(fd,&buf[i],sizeof(buf[i]));

                        //printf("%d ",buf[i]);

                }

                //printf("\n");

                semunlock(semid);

        }


        for(i=0; i<8; i++){

                close(pd[i]);

        }

        close(fd);

        return 0;

}



// client.c

#include <fcntl.h>

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>



#define fifoSize 1024

#define datablockNum 8


int main(void) {

        int pd[8], n, i,j,l, value=0;

        char computeNode[20] = "./computeNode";

        int fd;


        char clientData[8][12] = {

                "client0.dat",

                "client1.dat",

                "client2.dat",

                "client3.dat",

                "client4.dat",

                "client5.dat",

                "client6.dat",

                "client7.dat"

        };

         for(i=0; i<8; i++){

                computeNode[13] = '1'+i;

                if ((pd[i] = open(computeNode, O_WRONLY)) == -1){

                        perror("open");

                        exit(1);

                }

        }

        for(i=0; i<8; i++){

                if(fork() == 0){


                        /*write data*/

                        value = i;

                        if((fd = open(clientData[i],O_CREAT | O_WRONLY | O_TRUNC, 0600)) == -1){

                                perror("fopen");

                                exit(1);

                        }



                        for(l=0; l<fifoSize*datablockNum; l++){

                                write(fd, &value, sizeof(int));

                                write(pd[i], &value, sizeof(int));

                                value += 8;

                        }

                        printf("Client Process %d success\n", (int)getpid());

                        exit(1);

                }

                else wait(NULL);

        }

        for(i=0; i<8; i++){

                close(pd[i]);

                close(fd);

        }

        return 0;

}