thread 와 메모리 공유.

shout_maya의 이미지

(Posix thread)
안녕 하세요.. 쓰레드를 막 쓰다가 너무 삽질을 하고 나서...
어쨋든 결과는 냈는데 의문점이 생겨서 이렇게 질문 합니다.
Thread 를 쓸때
void *thread_func(void *arg)
이런 쓰레드 함수와 연결지어 씁니다.
pthread_create(... , thread_func, ...)
이렇게.. 그리고 thread_func 안에 다가는 thread 로 시작할
함수를 써주죠. 그래서 위에서 말한대로 코딩을 했습니다.
그리고 전역변수
Msg *head; // 메세지 큐를 만들기 위해.
Msg *tail; // head 와 tail 을 만들었습니다.
가 있었구요. 그리고 저걸 초기화 하는함수 init_message_queue를
만들었거든요. 거기 안에서 malloc(heap) 으로 할당합니다. 그런데
이 init_message_queue 가 thread_func 안에 있는 함수, 즉
thread 로 시작되는 함수에다가 넣었더니 "6번에 1번꼴"로
세그맨트 오류가 납니다. 그런데 저걸 thread_func 에 넣었더니
에러가 없어 지더군요!! -_-; 책에서 보니, 스택은 독립적으로
쓴다는데 그거랑 관련이 있는지.. Msg *head .. 등은 전역 변수라
별 상관이 없을것 같은데 말이죠. 난감 합니다 ...
참고로 swig 라는 툴로, 파이썬과 접합해서 쓰고 있는데
파이썬에서 C의 또 다른 함수를 통해 thread_func 를 부르는
방식입니다. 어떻게 이해를 해야 할까요?
조언 부탁드립니다. :-)

girneter의 이미지

python 과 연동하지 말고
이것저것 다 빼고
간단하게 C 로만 짜서 돌려보시죠
같은 에러가 나오는지.

역시 같은 에러가 난다면
여기다 소스를 올려주시면
문제를 찾기가 더 쉬울듯 싶습니다.

개념없는 초딩들은 좋은 말로 할때 DC나 웃대가서 놀아라. 응?

ocaptin의 이미지

shout_maya wrote:
(Posix thread)
안녕 하세요.. 쓰레드를 막 쓰다가 너무 삽질을 하고 나서...
어쨋든 결과는 냈는데 의문점이 생겨서 이렇게 질문 합니다.
Thread 를 쓸때
void *thread_func(void *arg)
이런 쓰레드 함수와 연결지어 씁니다.
pthread_create(... , thread_func, ...)
이렇게.. 그리고 thread_func 안에 다가는 thread 로 시작할
함수를 써주죠. 그래서 위에서 말한대로 코딩을 했습니다.
그리고 전역변수
Msg *head; // 메세지 큐를 만들기 위해.
Msg *tail; // head 와 tail 을 만들었습니다.
가 있었구요. 그리고 저걸 초기화 하는함수 init_message_queue를
만들었거든요. 거기 안에서 malloc(heap) 으로 할당합니다. 그런데
이 init_message_queue 가 thread_func 안에 있는 함수, 즉
thread 로 시작되는 함수에다가 넣었더니 "6번에 1번꼴"로
세그맨트 오류가 납니다. 그런데 저걸 thread_func 에 넣었더니
에러가 없어 지더군요!! -_-; 책에서 보니, 스택은 독립적으로
쓴다는데 그거랑 관련이 있는지.. Msg *head .. 등은 전역 변수라
별 상관이 없을것 같은데 말이죠. 난감 합니다 ...
참고로 swig 라는 툴로, 파이썬과 접합해서 쓰고 있는데
파이썬에서 C의 또 다른 함수를 통해 thread_func 를 부르는
방식입니다. 어떻게 이해를 해야 할까요?
조언 부탁드립니다. :-)

제가 잘 몰라서 그런전지... 사실 님 이야기 듣고 잘 이해가 안되네요.. 코드가 길지 않다면 같이 올려 보심이..

shout_maya의 이미지

헛! C에서만 간추려서 해봤더니, 역시 Thread 문제군요. 아래 에러나는 소스를
올립니다. main 에서 py_get_message 를 여러번 호출 하거든요.
실행 해보면. 5번에 한번 꼴로 세그맨테이션 에러가 납니다.

#include <gtk/gtk.h>
#include <pthread.h>


typedef struct _message
{
    int type; /* Message type */
    char *msg; /* Message data */
    struct _message *next;
}Msg;

char buffer[200];
Msg *head; /* 전역 변수 */
Msg *tail;    /* 전역 변수 */


char *py_get_message(void)
{
	Msg *get;

	if (head->next == tail) /* 에러 발생 지역 */
	{
		sprintf(buffer ,"-1 NULL");
		return buffer;
	}
	get = head->next;
	sprintf(buffer ,"%d %s", get->type, get->msg);

	head->next = get->next;

	free(get->msg);
	free(get);

	return buffer;
}



void py_put_message(int type, char *str)
{
	Msg *got = (Msg*)malloc(sizeof(Msg));
	Msg *temp;
      	got->type = type;
	
	got->msg = (char*)malloc(strlen(str) + 1);
	strcpy(got->msg, str);

	temp = head;

	while (temp->next != tail)
	{
		temp = temp->next;
	}
	temp->next = got;
	got->next = tail;
}


int main_f(void) /* Starting point */
{
	/*  Init Gtk+ */
	gtk_init(NULL, NULL);

	init_message_queue(); /* 여기에서 호출 하면 문제가 생김 */

	gtk_main();

	return 0;
}

void init_message_queue(void)
{
	head = (Msg*)malloc(sizeof(Msg));
	tail = (Msg*)malloc(sizeof(Msg));

	head->next = tail; 

	tail->next = tail;

	tail->type = -1;
	tail->msg = (char*)malloc(strlen("NULL") + 1);
	strcpy(tail->msg, "NULL");
}

void *thread_main(void *arg)
{
//	init_message_queue(); /* 이것이 main_f() 에 있을때 */
	                                  /*	  세그먼트 오류가 났었다. */
	main_f();                      /* main_f() 에 있는init_message_queue() 를 */
                                          /* 이쪽에 옮기면 에러가 안난다. */
}

int main()
{
	pthread_t t_id;

	pthread_create(&t_id, NULL, thread_main, NULL);
	py_get_message();
	py_get_message();
	py_get_message();
	py_get_message();
	py_get_message();
	py_get_message();
	py_get_message();
	
	return 0;
}

:-) got Linux?

charsyam의 이미지

뭐, 동기화 문제 같습니다만 ^^

thread_func 이 실행되기 전에 py_get_message 가 호출되면

당연히 죽겠죠? 실제로 py_get_message 호출전에

init_msg 어쩌고 함수가 호출되게 보장하면 에러가 안날꺼 같은데요? 고운 하루되세요.

=========================
CharSyam ^^ --- 고운 하루
=========================

shout_maya의 이미지

헉! 그러니까 Thread 함수가 실행이 되고, 그 타이밍이

py_get_message 보다 앞서지 못할경우게 그렇게 되는군요.

"동기화 문제"

오.................................................................................

왜 그 생각을 못했을까-_-; init_~ 이걸 좀더 일찍 실행되게 했을때

에러가 안났던 거군요.. 만세...ㅠ_ㅠ

감사 합니다.

하나의 깨달음을 얻었습니다 :D

:-) got Linux?

hanseok의 이미지

char *py_get_message(void) 
{ 
   Msg *get; 

   if (head->next == tail) /* 에러 발생 지역 */ 
   { 
      sprintf(buffer ,"-1 NULL"); 
      return buffer; 
   } 
   get = head->next; 
   sprintf(buffer ,"%d %s", get->type, get->msg); 

   head->next = get->next; 

   free(get->msg); 
   free(get); 

   return buffer; 
} 

이것 앞 부분에..
head->next
if ( head == NULL )

검사하면 깔끔해질수 있는 건가요? ^^;

동기화 문제라는 단어에서.. 생각을 해보았네요.

잠이 들어야지만 꿈을 꿀수 있는것인가?
우리는 항상 꿈을 쫓아 가며 살아가는 사람들..

댓글 달기

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