extern 변수 관련 문제입니다.

p952973의 이미지

하나의 헤더에 extern 변수를 선언한 후 두개의 메인에서 해당 extern 값에 접근합니다.

하나의 메인은 extern 값을 설정하고 나머지 하나는 extern값을 주기적으로 같은지 확인하는 내용으로 구현하려 했습니다.

하지만 값 설정은 되는데 그 값을 다른 메인에서 확인하지를 못합니다.

메인이 두개여서 문제가 되는건가요? 아니면 다른 문제가 있는걸까요 조언 부탁드립니다.

좋은 하루 보내세요!

a.c
 
#include<unistd.h>
#include<errno.h>
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<sys/time.h>
#include"a.h"
 
extern pid_t p;
 
int main(void){
	pid_t pid;
	scanf("%d", &pid);
 
	p = pid;
	printf("extern variable p changed...\n");
	printf("p : %d\n", p);
	exit(0);
}
 
 
b.c
 
#include<unistd.h>
#include<errno.h>
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<sys/time.h>
#include"a.h"
 
extern pid_t p;
 
int main(void){
	pid_t a = 1;
 
	while(1){
		sleep(1);
		printf("aaaaaaaaaaaaaa\n");
		printf("p : %d, a : %d \n", p, a);
		if(p == a){
			printf("in if( p == a )...\n");
			break;
		}
	}
	exit(0);
}
 
a.h
 
#include<unistd.h>
#include<errno.h>
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<sys/time.h>
 
pid_t p;
pchero의 이미지

a.c 에서는 올바른 접근이 되지만, b.c 에서는 접근이 안됐을 겁니다.
왜냐하면 pid_t p 에 값 설정이 안되어 있기 때문입니다.

a.c 에서는 초기화가 되었습니다

p = pid;

하지만 b.c 에서는 초기화가 안되었습니다.

아마도 다음과 같은 실행 파일 두개를 생성하셔서 테스트를 하신것 같습니다.

a.c 로 컴파일한 프로그램 a.out
b.c 로 컴파일한 프로그램 b.out

하지만... 위와 같은 두개의 실행파일을 생성했을 때, 두 개의 프로그램은 별개의 프로그램입니다.

생각컨데, a.out 과 b.out 에서 서로 같은 값을 확인하고 싶으셨던 거겠죠..
하지만 그렇게 하기 위해서는 작성하신 소스로는 불가능합니다.

서로 다른 프로세스(실행파일)끼리 동일한 값을 주고 받기 위해서는 IPC(Interprocess Communication) 라는 기술이 필요합니다.

세마포어, 네임드 큐(파이프), 소켓통신이 바로 그런 기술입니다. 혹은 파일을 이용할 수도 있구요.

제가 생각한 바가 맞다면, IPC로 검색해보시면 좋은 예제들을 찾으실 수 있을 겁니다.

---------------------------------
제일 왼쪽이 저입니다 :)

pchero의 이미지

아, 공유 메모리도 있습니다.

---------------------------------
제일 왼쪽이 저입니다 :)

twinwings의 이미지

틀리면 지적 부탁드립니다.

첫 번째

extern으로 선언은 주로 헤더파일에 이루어 지며, 정의는 구현부에 이루어 집니다.
(만약 헤더파일에 없이 구현부에만 존재할 경우 주로 static으로 정의하게 됩니다.)

따라서 extern 선언은 헤더파일로 옮겨야 되고, 정의부가 메인함수 위에 있어야 될 것 입니다.
(선언부와 정의부 순서 바꾸셔야 됩니다.)

<예시>

[in hello.h]
extern pthread_t pid;
 
[in hello.c]
pthread_t pid;

그리고 헤더파일에 변수 자체를 정의 할 경우, multiple definition reference 오류가 날 수 있습니다.

단, const로 정의 된 변수는 제외입니다. 헤더파일에 const 변수는 정의 할 수 있습니다.

자세한건 Effective C++(scott myers 저) 참조 하시구요.

두 번째

프로세스간 자원은 기본적으로 공유가 안됩니다.
(thread 단위에서는 heap과 전역변수는 공유 됩니다. stack 영역은 되지 않습니다.)

메인함수가 두개라는 말은 진입점이 두 개이고 즉, 프로세스가 2개 입니다.

따라서 extern으로 선언된 저 global variable은 물리적으로 서로 다른 위치에 존재합니다.
(가상 메모리상으로는 동일한 위치에 존재할 수도 있기에 주소를 출력해보면 동일한 주소 값이 나올 수 있습니다.
하지만 전혀 다른 자원입니다.)

따라서 바로 윗 분 답변처럼 프로세스 간 통신을 위해 IPC 기술들이 필요합니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.