socket에서 select사용에 관하여

kisungcho의 이미지

socket에서 select를 사용하고 있습니다.
select에서 5초간 대기하고 있다가 wakeup해야 하는데
무조건 깨어나서 cpu점유율이 100%입니다.
윈도우 호환되도록 프로그램 했는데 윈도우쪽에서는 5초간 대기하는데 리눅스에서는 대기하지 않습니다.

그래서 select에서timeout들어가는인자에 NULL을 주면 무한대기하다가 요청이 있을때만 깨어나서 cpu점유율이 아주 낮은데 쓰레드를 종료시에 select에 걸려서 프로그램이 종료되지 않습니다.

우선 두가지 질문이 있는데요. timeout이 되게 하려면 어떻게 해야하나요? 그리고 무한대기시에 select에서 깨어나게 하려면 어떻게 해야 하나요?

제가 네트웍을 잘 몰라서요 , 도움 바랍니다.
그럼 좋은 하루 되십시오.

static void*listen_thread(void* param)
{
	fd_set	rset, readset;
	SOCKET	news;
	struct timeval tv;
	struct	sockaddr_in addr;
	int	len;
	HANDLE	hThread;
	DWORD	tid;
	IO_PORT	*port;
					

	listen(g_socket, 5);
	FD_ZERO(&rset);
	FD_SET(g_socket, &rset);

	tv.tv_sec = 5;
	tv.tv_usec = 0;

	readset = rset;
	while(gb_linsten_run) {
		rset = readset;
		if(select(g_socket+1, &rset, NULL, NULL, &tv) <= 0 ||
		   !FD_ISSET(g_socket, &rset)) {
			continue;
		}

		len = sizeof(addr);
		news = accept(g_socket, (struct sockaddr *)&addr, &len);
		if(news == INVALID_SOCKET) {
			continue;
		}

		// check user count
		if(!is_additional_user_available()) {
			closesocket(news);
			continue;
		}

		port = (IO_PORT *)mem_alloc(sizeof(IO_PORT));
		if(!port) {
			closesocket(news);
			continue;
		}

		port->pSerialLink = NULL;
		port->s = news;
		port->addr = addr;
		port->timeout = GetTimeout();

		stat = pthread_create(&hThread, NULL, p_service, (void*)port);
		if(stat == -1) {
			close(news);
			mem_free(port);
			continue;
		}


	}

	gh_listen_thread = NULL;
	return 0;
}

static BOOL init_listen_thread(int port)
{
	DWORD	tid;

	g_socket = create_socket();
	if(g_socket == INVALID_SOCKET) {
		return FALSE;
	}

	if(!bind_socket(g_socket, port)) {
		close(g_socket);
		g_socket = INVALID_SOCKET;
		return FALSE;
	}
	gb_dvrp_linsten_run = TRUE;
	stat = pthread_create(&gh_listen_thread , NULL, 0, listen_thread, NULL);

	if(stat == -1) {
		close(g_socket);
		g_socket = INVALID_SOCKET;
		return FALSE;

	}

	return TRUE;
}

static BOOL term_listen_thread()
{
	gb_linsten_run = FALSE;

	if(gh_listen_thread) {
            close(g_dvrp_socket);
            pthread_join(gh_listen_thread, NULL);
        }
	while(gh_listen_thread) {
		usleep(50);
	}

	
	if(g_socket) {
		close(g_socket);
		g_socket = INVALID_SOCKET;
	}	
	return TRUE;
}
IsExist의 이미지

select 호출전에 tv 값 셋팅하게 수정해 보세요.

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

ssehoony의 이미지

select 함수는
5번째 tv 파라미터의 값을 리턴할 때 변경합니다.
그러므로 tv는 select를 호출하기 전에 매번 셋팅해 줘야 합니다.

man 페이지에 보면 위의 사실에 대해 주의를 주고 있습니다.
man 페이지를 꼼꼼히 읽어 보시면 도움이 될거에요.

익명 사용자의 이미지

FD_ZERO(&rset);
FD_SET(g_socket, &rset);

tv.tv_sec = 5;
tv.tv_usec = 0;

일단 이 4줄을 select() 문 바로 위로 옮기세요.

kisungcho의 이미지

man page를 읽어보긴 했는데 자세히 못읽어봤네요.
답변주셔서 고맙습니다.
즐거운 크리스마스 보내시기 바랍니다.

댓글 달기

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