[Linux] key & serial 멀티 프로세서로 처리하기
develop/dogvelop 2006. 12. 9. 13:26
fork(), signal, poll()을 사용한 프로그램이다.
/**
* 멀티프로세서 프로그램 *
* 부모 프로세서에서는 전용선(ttyS3)에서 데이터를 읽어오고(1byte)
* set_timer()로 지정한 시간이 경과하면 자식프로세서를 종료시키고 종료한다.
*
* 자식 프로세서는 키입력을 받아오고, 종료(CANCEL)키가 들엉오면,
* 부모프로세서에게 종료(SIGTERM)시그널을 보내고 종료한다.
*/
#include "include.h"
#define MOL
#include "app_pub.h"
#include "app_def.h"
#include "app_func.h"
int main(void)
{
int pid,ppid, cnt,child,parent,status;
struct pollfd Event;
sigset_t set1,oldset,pend;
if ((pid = fork()) < 0)
{
perror("fork() Error");
exit(2);
}
else
if (pid != 0)
{ //parent
sio_set(PRIVATE_PORT, B9600);
Event.fd = fd;
Event.events = POLLIN | POLLERR;
//시그널 집합 set1을 비우고,
sigemptyset(&set1);
// SIGALRM만 추가한다.
sigaddset(&set1, SIGALRM);
// SIGALRM을 제외한 모든 시그널은 블록되고,
// 기존의 시그널은 oldset에 저장한다.
// 현재 프로시져 내의 모든 시그널에 영향을 미친다.(set_timer포함)
sigprocmask(SIG_BLOCK,&set1,&oldset);
memset(tempbuf,0,sizeof(tempbuf));
rlen = 0;
// setitimer()로 timeout 10초 설정
set_timer(10);
parent = 0;
while(waitpid(pid, &status, WNOHANG)==0)
{
cnt = poll((struct pollfd *)&Event, 1, 1*1000);
if (cnt < 0)
{
perror("poll() Error");
exit(2);
}
else
if (!cnt)
{
//poll()로 1초마다, 시그널을 체크한다.
//블목화된 시그널 가져온다.
sigpending(&pend);
// set_timer()는 지정한 시간이 초과되면,
// SIGALRM 시그널을 발생시킨다.
// sigismember()로 pend에 있는 가져온 시그널을 체크
// SIGALRM시그널이면, 부모&자식프로세서를 종료시킨다.
if (sigismember(&pend,SIGALRM))
{
if (sigismember(&pend, SIGALRM))
printf("Get SIGALRM\n");
printf("Time Out\n");
sio_close(PRIVATE_PORT);
//프로시져의 시그널들을 oldset으로 변경한다.
sigprocmask(SIG_SETMASK,&oldset,NULL);
// set_timer을 풀어야 나중에 발생할 수도 있는
// SIGALRM시그널로 인한 종료를 막는다.
release_timer();
// 자식 프로세서에게 정상종료한다.
kill(pid,SIGTERM);
return 1;
}
printf("parent = %d\n",parent++);
}
else
if (cnt)
{
RCH = com_getc();
tempbuf[rlen++] = RCH;
printf("tempbuf>>\n");
printf("%s\n",tempbuf);
}
}
printf("Get status : %d\n",status);
sio_close(PRIVATE_PORT);
return status;
}
else
{
if ((keyhandle = open("/dev/key",O_RDWR)) < 0)
{
perror("open key Fail");
exit(3);
}
Event.fd = keyhandle;
Event.events = POLLIN | POLLERR;
child = 0;
printf("parent PID : %u\n",getppid());
printf("child PID : %u\n",getpid());
while(1)
{
cnt = poll((struct pollfd *)&Event, 1, 1000);
if (cnt < 0)
{
perror("key poll() Error");
exit(3);
}
else
if (!cnt)
{
printf("child = %d\n",child++);
}
else
if (cnt)
{
RCH = GetKey();
if (RCH == CANCEL)
{
close(keyhandle);
//부모프로세서에게 정상종료 시그널을 보낸다.
kill(getppid(), SIGTERM);
exit(3);
}
else printf("RCH = 0x%X\n",RCH);
}
}
}
}
/**
* 멀티프로세서 프로그램 *
* 부모 프로세서에서는 전용선(ttyS3)에서 데이터를 읽어오고(1byte)
* set_timer()로 지정한 시간이 경과하면 자식프로세서를 종료시키고 종료한다.
*
* 자식 프로세서는 키입력을 받아오고, 종료(CANCEL)키가 들엉오면,
* 부모프로세서에게 종료(SIGTERM)시그널을 보내고 종료한다.
*/
#include "include.h"
#define MOL
#include "app_pub.h"
#include "app_def.h"
#include "app_func.h"
int main(void)
{
int pid,ppid, cnt,child,parent,status;
struct pollfd Event;
sigset_t set1,oldset,pend;
if ((pid = fork()) < 0)
{
perror("fork() Error");
exit(2);
}
else
if (pid != 0)
{ //parent
sio_set(PRIVATE_PORT, B9600);
Event.fd = fd;
Event.events = POLLIN | POLLERR;
//시그널 집합 set1을 비우고,
sigemptyset(&set1);
// SIGALRM만 추가한다.
sigaddset(&set1, SIGALRM);
// SIGALRM을 제외한 모든 시그널은 블록되고,
// 기존의 시그널은 oldset에 저장한다.
// 현재 프로시져 내의 모든 시그널에 영향을 미친다.(set_timer포함)
sigprocmask(SIG_BLOCK,&set1,&oldset);
memset(tempbuf,0,sizeof(tempbuf));
rlen = 0;
// setitimer()로 timeout 10초 설정
set_timer(10);
parent = 0;
while(waitpid(pid, &status, WNOHANG)==0)
{
cnt = poll((struct pollfd *)&Event, 1, 1*1000);
if (cnt < 0)
{
perror("poll() Error");
exit(2);
}
else
if (!cnt)
{
//poll()로 1초마다, 시그널을 체크한다.
//블목화된 시그널 가져온다.
sigpending(&pend);
// set_timer()는 지정한 시간이 초과되면,
// SIGALRM 시그널을 발생시킨다.
// sigismember()로 pend에 있는 가져온 시그널을 체크
// SIGALRM시그널이면, 부모&자식프로세서를 종료시킨다.
if (sigismember(&pend,SIGALRM))
{
if (sigismember(&pend, SIGALRM))
printf("Get SIGALRM\n");
printf("Time Out\n");
sio_close(PRIVATE_PORT);
//프로시져의 시그널들을 oldset으로 변경한다.
sigprocmask(SIG_SETMASK,&oldset,NULL);
// set_timer을 풀어야 나중에 발생할 수도 있는
// SIGALRM시그널로 인한 종료를 막는다.
release_timer();
// 자식 프로세서에게 정상종료한다.
kill(pid,SIGTERM);
return 1;
}
printf("parent = %d\n",parent++);
}
else
if (cnt)
{
RCH = com_getc();
tempbuf[rlen++] = RCH;
printf("tempbuf>>\n");
printf("%s\n",tempbuf);
}
}
printf("Get status : %d\n",status);
sio_close(PRIVATE_PORT);
return status;
}
else
{
if ((keyhandle = open("/dev/key",O_RDWR)) < 0)
{
perror("open key Fail");
exit(3);
}
Event.fd = keyhandle;
Event.events = POLLIN | POLLERR;
child = 0;
printf("parent PID : %u\n",getppid());
printf("child PID : %u\n",getpid());
while(1)
{
cnt = poll((struct pollfd *)&Event, 1, 1000);
if (cnt < 0)
{
perror("key poll() Error");
exit(3);
}
else
if (!cnt)
{
printf("child = %d\n",child++);
}
else
if (cnt)
{
RCH = GetKey();
if (RCH == CANCEL)
{
close(keyhandle);
//부모프로세서에게 정상종료 시그널을 보낸다.
kill(getppid(), SIGTERM);
exit(3);
}
else printf("RCH = 0x%X\n",RCH);
}
}
}
}
'develop > dogvelop' 카테고리의 다른 글
mingw + eclipse로 windows에서 개발하기 (0) | 2006.12.15 |
---|---|
[리눅스]메세지 큐를 이용한 serial & key & timer check (0) | 2006.12.11 |
[리눅스] sleep & usleep (0) | 2006.11.29 |
[리눅스] 현재 시간을 자신이 원하는 포맷으로 출력하기 (0) | 2006.08.22 |
프로세스 찾아서 지우고 실행하기 (0) | 2006.08.21 |