LINUX.ORG.RU

Как правильно обрабатывать сокеты в потоках?

 ,


1

1

(продолжение этого).

Итак, решил я своему «видеотранслятору» сделать жестокую проверку. Наклепал код:

<html>
<head><title>Simple streaming test</title>
<script>
	var img = new Image();
	img.onload = function(){
		document.getElementById("animage").src = img.src;
		setTimeout(stream_next, 50);
	}
	function stream_next(){
		img.src = "http://localhost:54321/" + Math.random() + ".jpg";
	}
</script>
</head>
<body onload="stream_next();">
<img id="animage">
</body>
</html>
Запустил демона, открыл эту страничку. Поначалу видео вполне себе отображалось. Но на каком-то моменте произошел затык. Причем, демон вообще перестал отзываться даже на запросы отдельных кадров! В отладочных сообщениях пишет «accept»:
		DBG("accept");
		newsock = accept(sock, (struct sockaddr*)&their_addr, &size);
		if(newsock <= 0){
			WARN("accept()");
			continue;
		}
		pthread_t handler_thread;
		if(pthread_create(&handler_thread, NULL, handle_socket, (void*) &newsock) < 0)
			WARN("pthread_create()");
и ... тишина.

По идее, если бы кончились файловые дескрипторы, accept вернул бы ошибку → появилось бы соответствующее сообщение.

Следовательно, косяк в потоках.

Не может ли быть такого, что у меня понасоздавалась куча потоков, к которым не было pthread_join и из-за этого новые потоки создаваться перестали??

Как вообще в таких случаях обрабатывают потоки, чтобы не было «зомби»? Может быть, впилить пул потоков и в отдельном потоке запускать на каждый новый pthread_join? Вообще ничего разумного в голову не приходит...

☆☆☆☆☆

Так и есть: добавил в отладочный выхлоп отображение идентификатора потока: от кадра к кадру идентификатор увеличивается, в итоге достигает предела и кирдык.

Как "отмотать" на начало?

Eddy_Em ☆☆☆☆☆
() автор топика
man pthread_attr_setdetachstate
...........
PTHREAD_CREATE_DETACHED
              Threads that are  created  using  attr  will  be  created  in  a
              detached state.
imb ★★
()
Ответ на: комментарий от imb

Спасибо! Можно и вот так:

		pthread_t handler_thread;
		if(pthread_create(&handler_thread, NULL, handle_socket, (void*) &newsock) < 0)
			WARN("pthread_create()");
		pthread_detach(handler_thread);
В этом случае ресурсы высвобождаются и косяков не будет.

Забавно: похоже, такой способ передачи "видео" не вызывает утечки памяти у браузеров (в отличие от потокового mjpeg). А я уже с вебсокетами заморачиваться начал...

В общем, реализую оба варианта, абы было.

Eddy_Em ☆☆☆☆☆
() автор топика

if(pthread_create(&handler_thread, NULL, handle_socket, (void*) &newsock) < 0)

Нужно не так проверять эту функцию.

If successful, the pthread_create() function shall return zero; otherwise, an error number shall be returned to indicate the error.

Т.е. нужно проверять так:

if(pthread_create(&handler_thread, NULL, handle_socket, (void*) &newsock) != 0)

Sorcerer ★★★★★
()

Забавно: оставил эту штуку работать, таймаут поднял до 100мс, чтобы не сильно шустро молотила. Ушел на обед. Прихожу, а тут:

Assertion atomic_int_get_gcc(&s->buffers_queued) >= 1 failed at libavdevice/v4l2.c:516

Хотя, теоретически такого быть не должно: не так уж и шустро я опрашиваю.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

А, ладно: запихну демон в inittab с флагом respawn.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от tensai_cirno

Да ладно. Я уже обычный итератор добавил. Сильно сомневаюсь, что когда он переполнится, в кэше еще что-нибудь останется.

Реализовал на вебсокетах видео. Еще останется добавить переключалку (возможно, автоматическую) на обычное потоковое, и можно будет считать прожект выполненным на стадии "бета".

Eddy_Em ☆☆☆☆☆
() автор топика

<html>
<head><title>Simple streaming test</title>
<script>

Лол, кто-то бился в грудь, что он идейный, и что высокоуровневые языки для быдла.

anonymous
()
Ответ на: комментарий от anonymous

А что, есть возможность писать веб-морды без жабоскрипта? А ну-ка, давай пример!

Eddy_Em ☆☆☆☆☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.