// 클라이언트에서 정렬하는 클라이언트 오리엔티드 방식과 다르게 서버의 어디로 갈지 미리 정하고 통신하는 방법
// 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
#define clientSize 8192
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, total, gap;
memset(&start, 0, sizeof(start));
memset(&end, 0, sizeof(end));
memset(&gap, 0, sizeof(gap));
memset(&total, 0, sizeof(total));
int fd;
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);
}
}
off_t off;
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++){
while(1){
semlock(semid);
gettimeofday(&start, NULL);
if((n=read(pd[i],rbuf,sizeof(int)*fifoSize))>0){
gettimeofday(&end, NULL);
gap.tv_usec = end.tv_usec - start.tv_usec;
gap.tv_sec = end.tv_sec - start.tv_sec;
total.tv_sec += gap.tv_sec;
if(gap.tv_usec>0){
total.tv_usec += gap.tv_usec;
}
//printf("communication time : %ld %ld\n", gap.tv_sec, gap.tv_usec);
memset(&start, 0 ,sizeof(start));
memset(&end, 0, sizeof(end));
memset(&gap, 0, sizeof(gap));
//printf("communication time : %ld %ld\n", total.tv_sec, total.tv_usec);
for(j=0; j<(n/4); j++){
buf[bufoff] = rbuf[j];
bufoff++;
}
//printf("child unlock\n");
semunlock(semid);
}
else {
//printf("child unlock\n");
semunlock(semid);
break;
}
}
}
//printf("communication time : %ld %ld\n", total.tv_sec, total.tv_usec);
/*gettimeofday(&end, NULL);
gap.tv_usec = end.tv_usec - start.tv_usec;
gap.tv_sec = end.tv_sec - start.tv_sec;
printf("communication time : %ld %ld\n", gap.tv_sec, gap.tv_usec);
total.tv_sec += gap.tv_sec;
if(gap.tv_usec < 0){
total.tv_usec += gap.tv_usec;
}*/
printf("communication time : %ld %ld\n", total.tv_sec, total.tv_usec);
printf("Child Server:");
memset(&start, 0 ,sizeof(start));
memset(&end, 0, sizeof(end));
memset(&gap, 0, sizeof(gap));
semlock(semid);
//gettimeofday(&start,NULL);
sort(buf, bufoff);
//gettimeofday(&end, NULL);
//gap.tv_usec = end.tv_usec - start.tv_usec;
//gap.tv_sec = end.tv_sec - start.tv_sec;
printf("sort time : %ld %ld\n", gap.tv_sec, gap.tv_usec);
//total.tv_sec += gap.tv_sec;
//if(gap.tv_usec < 0){
// total.tv_usec += gap.tv_usec;
//}
memset(&start, 0 ,sizeof(start));
memset(&end, 0, sizeof(end));
memset(&gap, 0, sizeof(gap));
gettimeofday(&start,NULL);
write(fd,buf,sizeof(buf));
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 %ld\n",gap.tv_sec, gap.tv_usec);
total.tv_sec += gap.tv_sec;
if(gap.tv_usec < 0){
total.tv_usec += gap.tv_usec;
}
printf("total time : %ld초 %ldus\n", total.tv_sec, total.tv_usec);
printf("sizeof server:%d\n", bufoff);
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++){
while(1){
semlock(semid);
//printf("parent lock\n");
if((n=read(pd[i],rbuf,sizeof(int)*fifoSize))>0){
for(j=0; j<(n/4); j++){
buf[bufoff] = rbuf[j];
bufoff++;
}
//printf("parent unlock\n");
semunlock(semid);
}
else{
//printf("parent unlock\n");
semunlock(semid);
break;
}
}
}
semlock(semid);
printf("Parent Server: ");
sort(buf,bufoff);
// for(i=0;i<bufoff;i++){
write(fd,buf,sizeof(buf));
// printf("%d ",buf[i]);
//}
//printf("\n");
printf("sizeof server: %d\n", bufoff);
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
void sort(int* buf, int size){
int i,j, temp;
for(i=0; i<size; i++){
for(j=0; j<size; 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, value_s=0,value_c=0, bufoff=0;
int buf[8][fifoSize*datablockNum];
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++){
value_s = i;
value_c = value_s+fifoSize;
bufoff=0;
for(l=0; l<datablockNum/2; l++){
for(j=0; j<fifoSize; j++){
buf[i][bufoff] = value_s;
bufoff++;
value_s += 8;
if((value_s-i)%1024 == 0 && (value_s-i) >= 1024 ){
value_s += 1024;
}
}
for(j=0; j<fifoSize; j++){
buf[i][bufoff] = value_c;
value_c += 8;
bufoff++;
if((value_c-i)%1024 == 0){
value_c += 1024;
}
}
}
}
for(i=0; i<8; i++){
if(fork() == 0){
if((fd = open(clientData[i], O_CREAT | O_WRONLY | O_TRUNC, 0600)) == -1){
perror("fopen");
exit(1);
}
if(write(pd[i], buf[i], sizeof(buf[i]))==-1){
perror("write error");
}
sort(buf[i], sizeof(buf[i])/4);
if(write(fd,buf[i],sizeof(buf[i]))==-1){
perror("file write error");
}
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;
}
'리눅스 프로그래밍' 카테고리의 다른 글
[운영체제] 세마포어를 사용해 프로세스통신 구현해보기_Client방식 (0) | 2018.12.22 |
---|---|
[운영체제] 세마포어를 사용해 프로세스통신 구현해보기_Basic방식 (0) | 2018.12.22 |