자식 프로세스 여러개 생성 후 신호로 종료시킨 뒤, 실행 시간의 합 출력하는 프로그램... 어디에 문제가 있을까요???

inviolable의 이미지

#include <unistd.h>
#include <signal.h>
#include <sys/times.h>
#include <stdio.h>
#include <time.h>
 
long int i1=0,i2=0,i3=0,gaptime=0;
long int time1=0,time2=0,time3=0;
long int tick;
int num = 0;
int num1 = 0;
 
static void sig_int(int signo)
{
	printf("child caught\n");
 
	num1++;
	printf("num1 = %d\n",num1);			
 
}
 
int main(void)
{
	int statlot;
	pid_t pid,pid1;
	struct tms buf;
	tick = sysconf(_SC_CLK_TCK);//nano second can be acquired
 
	printf("time = %ld\n",times(&buf)/tick);
 
 
	struct sigaction sig;
	sig.sa_handler = sig_int;
	sigemptyset(&sig.sa_mask);
	sig.sa_flags = 0;
	sigaction(SIGINT,&sig,NULL);
 
 
	pid1 = getpid();
 
 
 
	i1 = times(&buf)/tick;
	if((pid = vfork()) < 0)//for sharing variable between parent and child
		printf("fork error 1\n");
 
	if((pid1 = fork()) < 0)
		printf("fork error\n");
	else if(pid1 == 0)
	{
		sleep(5);
		printf("before kill\n");
		kill(pid,SIGINT);
		printf("after kill\n");
		_exit(0);
	}
	else
		_exit(0);//여기까지 보시면 됩니다.
 
	printf("after pid1 process\n");
 	if(pid == 0)//pid is return value, not child pid
	{
 
 
 
		num++;
		printf("num = %d\n",num);
 
 
		pause();
		time1 = times(&buf)/tick;
		gaptime += (time1 - i1);
		printf("gaptime = %ld\n",gaptime);
 
		_exit(0);
 
	}
 
 
	sleep(5);
 
 
 
 
	i2 = times(&buf)/tick;
	if((pid = vfork()) < 0)
		printf("fork error2\n");
 
	if((pid1 = fork()) < 0)
		printf("fork error\n");
	else if(pid1 == 0)
	{
		sleep(7);
		kill(pid,SIGINT);
 
	}
	else 
		_exit(0);
 
	if(pid == 0)
	{
 
		num++;
		printf("num = %d\n",num);
 
		pause();
		time2 = times(&buf)/tick;
		gaptime += (time2 - i2);
		printf("gaptime = %ld\n",gaptime);
 
		_exit(0);
	}
 
	sleep(7);
	if((pid1 = fork()) < 0)
		printf("fork error\n");
	else if(pid1 == 0)
	{
		sleep(5);
		kill(pid,SIGINT);
		_exit(0);
	}
	else
		_exit(0);
 
 
 
	i3 = times(&buf)/tick;
	if((pid = vfork()) < 0)
		printf("fork error 3\n");
 
	if((pid1 = fork()) < 0)
		printf("fork error\n");
	else if(pid1 == 0)
	{
		sleep(9);
		kill(pid,SIGINT);
		_exit(0);
	}
 
	if(pid == 0)
	{
 
		num++;
		printf("%ld\n", time3);
 
		pause();
		time3 = times(&buf)/tick;
		gaptime += (time3 - i3);
 
		_exit(0);//for not flushing stream
 
	}
 
	sleep(9);
 
	if(num == 3)
	{
		printf("child processes's running sum time = %ld seconds\n", gaptime);
	}
	return 0;
 
}

코드가 조금 긴데, 전체 소스구요. 만들고자 하는 프로그램은 위와 같습니다. 주석으로 //여기까지 읽으시면 됩니다 라고 되어있는 부분까지만 읽으시고 나머지는 계속 그거 반복이니까 보실 필요는 없으실 듯 합니다.
child caught
num1 = 1
after kill
child caught
num1 = 1
before kill
after kill
(여기서 중지됐는지 아무리 기다려도 출력이 안됨)

코드를 이렇게도 바꿔보고 저렇게도 바꿔봤지만, 문제는 fork함수로 생성한 신호 주기 프로세스가 코드 순서대로 수행되고 종료되어야 하는데 이상하게 신호 처리부가 두번 이상 호출된다든지, 디버깅을 위해 printf문을 넣으면 코드순서대로 실행이 안되고 이상하게 kill이 먼저 실행됐다가 킬 위에 printf문이 실행되고 이런 식이 되기도 하고 아예 kill을 안하고, 위아래 printf문만 실행되기도 하고 그러네요... 왜 그런건지 전혀 종잡을 수가 없습니다. 도움을 주세요.

inviolable의 이미지

프갤에 올렸던 내용인데...(어떤 사이트인지 정확히 밝히면 광고라 안되겠죠.ㅜㅜ 아무튼 프로그래밍 커뮤니티 사이트입니다.)
다시 일일이 치기도 귀찮고 해서 그대로 복사해옵니다. 말투가 거기는 반말투를 많이 쓰는데 여기에서는 안 쓰는거 알지만 그대로 복사해온 거라는 점을 감안하셔서 화내지 마셨으면 합니다.ㅜㅜ

//여기까지 읽으면 됨 여기까지 읽으면 되 나머지는 반복 되는 부분이니까.

자식 프로세스를 여러 개 생성하고 신호로 죽인뒤, 마지막에 실행시간의 합 출력하는 프로그램인데...

간단하게 소스 설명을 하자면, vfork로 자식 프로세스 생성(자식 프로세스 공간에서 선언된 변수가 자식 프로세스 종료시 없어지면 실행시간을 구할 길이 없으니까 부모와 변수가 공유되는 vfork함수를 이용한거야.)하고 자식 프로세스는 pause한 뒤(앞 뒤로 times함수 호출해서 저장 해둬 나중에 실행 시간 구하려고...) 자식 프로세스 이전에 또 fork로 프로세스를 생성해서 이 프로세스는 몇초간 sleep한 뒤, vfork로 생성한 자식 프로세스를 sigint신호를 보내. 그럼 vfork로 생성한 프로세스가 pause에서 깨어나겠지 그럼 나머지 작업 수행하고 종료되. //신호까지 배운 지식으로 충분히 완벽하게 만들 수 있는 프로그램이라니까 이상한 딴지는 걸지마 뭐 ipc를 이용하라느니 이런거 그건 맨 끝이나 되야 나올 내용이니까...

근데 문제는 fork로 생성한 프로세스(vfork로 생성한 프로세스한테 sigint신호 주는 프로세스)가 코드순서대로 실행이 안되고 printf문 -> kill함수 -> printf문 순서인데 이상하게 kill함수가 2번 호출되는지 신호 처리부가 거기에서만 2번 호출되고 fork프로세스 if문에서도 순서가 뒤죽박죽이야. kill함수가 제일 먼저실행되기도 하고 아예 kill함수가 호출안되고 앞뒤 printf문만 실행되기도해... 문제가 뭔지 알려줘.ㅜㅜ

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.