Archiwum kategorii: Developer

Kodowanie asynchroniczne w C# na web-ie, czyli czemu w końcu przydadzą się procesory wielordzeniowe

No dobra, po epokowej przerwie (ostatnio wpis jakieś 4 lata temu?!!) mam coś ciekawego.

Szybki up-to-date, wkręciłem się w nowego „dotneta” (.NET core) a ściślej ASP.NET Core.

Jak zwykle przeglądając czeluście internetu trafiłem tutaj: https://caleblloyd.com/software/net-core-mvc-thread-pool-vs-async/

Wiedziałem że słowo kluczowe async, await w programowaniu usług sieciowych w C# musi mieć jakiś większy sens i treść i oto wytłumaczenie. No więc nie byłbym sobą gdybym nie zmaścił jakiegoś benchmarka. Postanowiłem za autorem użyć podobnego scenariusza i przetestować metody (kod ASP.NET core WebAPI):

// GET api/values/sleep
[HttpGet("sleep")]
public string GetSleep()
{
    Thread.Sleep(1000);
    return Process.GetCurrentProcess().Threads.Count.ToString();
}

// GET api/values/delay
[HttpGet("delay")]
async public Task<string> GetDelay()
{
    await Task.Delay(1000);
    return Process.GetCurrentProcess().Threads.Count.ToString();
}

No i dobra, ale przydałby się jakiś kod testowy C# a nie odwołanie (jak caleblloyd) do pakietu stress-testującego. No to wymyśliłem takie coś (fragment kodu aplikacji GUI):

private async Task SyncAcynsWebProcessing(CancellationToken token, int seconds2Run = 60, int threadCount = 50)
{
	Stopwatch watch = new Stopwatch(), global_watch = new Stopwatch();
	int run_times = 0;
	string url = txtDebug.Text.Trim().Split(new[] { '\r', '\n' }).FirstOrDefault();
	global_watch.Start();

	while (true)
	{
		if (!token.IsCancellationRequested &&
			global_watch.ElapsedMilliseconds > (seconds2Run * 1000))//do this procedure X number of seconds
			break;

		var all_tasks = new Task<int>[threadCount];
		watch.Reset();
		watch.Start();
		for (int i = 0; i < threadCount; i++)//create-and-run x tasks
		{
			all_tasks[i] = Task.Run(async () =>
			{
				try
				{
					using (var client = new HttpClient())
					{
						var stackContent = await client.GetAsync(url, token);
						var response = await stackContent.Content.ReadAsStringAsync();
						if (response.Length > 10)
						{
							return response.Length;
						}
						else
						{
							if (int.TryParse(response, out int j))
								return j;
							return -1;
						}
					}
				}
				catch (Exception ex)
				{
					this.Dispatcher.Invoke(() =>//run something on UI thread
					{
						txtDebug.AppendText(ex.ToString());
					});
					return -2;
				}
			}, token);
		}
		//wait for all threads to complete
		await Task.WhenAll(all_tasks).ContinueWith((all_results) =>
		{
			watch.Stop();
			this.Dispatcher.Invoke(() =>//run something on UI thread
			{
				string comm = "";
				txtDebug.AppendText(Environment.NewLine);
				foreach (var res in all_results.Result)
				{
					txtDebug.AppendText(comm + res);
					comm = ",";
				}
				txtDebug.AppendText($"{Environment.NewLine}ElapsedMilliseconds: {watch.ElapsedMilliseconds}");
			});

			watch.Reset();
			foreach (Task<int> tsk in all_tasks) tsk.Dispose();
			all_tasks = null;
		}, token);
		//await Task.Delay(250).ConfigureAwait(false);
		run_times++;
	}

	this.Dispatcher.Invoke(() =>//run something on UI thread
	{
		txtDebug.AppendText($"{Environment.NewLine}----------{Environment.NewLine}Bottom line summary: {global_watch.ElapsedMilliseconds}"
			+ $" run {run_times} times");
	});
}

To cudo wykonuje przez zadaną ilość sekund (domyślnie 60) działanie polegające na zasypywaniem serwera wielu króciutkich zapytań i sumuje odpowiedzi (które są ilością sumą wątków robocznych .NET). Robione jest to specjalnie przez X sekund i z zadaną ilością wątków (domyślnie 50) aby równo obciążyć (czyt. dobić) serwer.

Wyniki, dla metody używającej synchronicznych wywołań (metoda http://localhost:4553/sleep):

http://localhost:4553/sleep
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26
Elapsed millis: 9053
26,26,26,26,27,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27
Elapsed millis: 7169
29,29,29,29,29,29,29,30,29,29,30,30,30,30,31,30,30,30,30,36,30,31,36,31,35,35,35,31,35,31,36,31,36,35,36,36,36,36,36,36,36,36,36,35,36,36,36,36,35,36
Elapsed millis: 5199
37,37,37,37,37,37,37,37,37,37,37,37,38,37,38,38,38,38,38,38,38,38,38,38,39,38,38,39,38,39,39,39,39,39,39,39,39,39,39,39,38,39,39,39,39,39,39,39,39,39
Elapsed millis: 4105
39,39,39,39,39,39,39,39,39,39,40,39,39,40,40,39,40,40,39,39,40,40,40,40,40,40,40,40,40,40,40,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,40,41
Elapsed millis: 3706
42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,43,42,42,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,42,43,43,43,43,43,43,43,43,43,43
Elapsed millis: 3126
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64
Elapsed millis: 2128
65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65
Elapsed millis: 2073
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66
Elapsed millis: 2082
67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67
Elapsed millis: 2066
67,67,67,67,67,67,67,67,67,67,67,64,67,67,67,67,67,67,67,67,64,67,67,67,64,64,67,64,67,64,64,67,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64
Elapsed millis: 2098
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,63,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64
Elapsed millis: 2066
64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,63,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64
Elapsed millis: 2122
69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,68,69,69,69
Elapsed millis: 2059
70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,69,70,70
Elapsed millis: 1798
71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71
Elapsed millis: 1136
71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,70,70,71,71
Elapsed millis: 1169
71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,70,71,71,71,71,71,71
Elapsed millis: 2113
71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,70,71,71,71,71,71,71,71,71,71,71,71,71,71
Elapsed millis: 2108
71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,70,71,71,71,71,71,71,71,71,71,71,71,71
Elapsed millis: 2063
75,75,75,75,75,75,75,71,71,71,71,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,74,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75
Elapsed millis: 2056
----------

Took 61565 millis to run 21 times

A teraz to samo dla metody wykorzysujące asyncrhoniczne wyowłania (async/await http://localhost:4553/delay):

http://localhost:4553/delay
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1150
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1075
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1058
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1059
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1095
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1049
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1082
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1073
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1070
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1076
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1062
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1080
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1059
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1081
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1074
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1075
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1066
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1087
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1062
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1091
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1070
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1073
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1079
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1070
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1060
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1085
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1063
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1095
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1063
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1107
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1077
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1087
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1076
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1054
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1068
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1085
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1075
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1079
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1068
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1089
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1074
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1064
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1062
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1061
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1059
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1078
44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
Elapsed millis: 1066
44,45,45,44,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,44,44,45,44,44,45,44,44,45,44,44,44,44,44,44,44
Elapsed millis: 1070
45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
Elapsed millis: 1061
45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
Elapsed millis: 1069
45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
Elapsed millis: 1094
45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
Elapsed millis: 1067
45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
Elapsed millis: 1043
45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
Elapsed millis: 1094
45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
Elapsed millis: 1069
45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
Elapsed millis: 1077
----------

Took 60225 millis to run 56 times

Jak widać dla takiego samego czasu działania (około 60 sekund) ilość obsłużonych zadań jest przeszło dwa razy większa – 2x przyspieszenie. 21 vs 56

Monitorowanie web-cam’em

Dawno dawno temu w odległej galaktyce… kupiłem kamerkę 😉

Była to VF0420 Live! Cam Vista IM
Szybko znudziła mi się jako zabawka do „pogaduch sieciowych” i postanowiłem zrobić z niej użytek do monitorowania obiektu czy też posesji.
Dlatego też, wystawiłem ją przez okno aby obserwowała wejście na teren działki, podpiąłem pod maszynę Linuksową (Gentoo).

Użyłem „kernelowych” sterowników gspca(model ov519) oraz zainstalowałem soft do robienia zrzutów, MJPG-Streamer.
MJPG-Streamer udostępnia stream w formacie MJPG (który na dobrą sprawę generuje sama kamera) z bardzo małym narzutem na CPU.
Oprócz streamu można też łapać pojedyncze klatki obrazu JPG co właśnie najbardziej mnie interesowało.
Skrypt bash podpięty do cron’a co 10 minut pobiera klatkę obrazu z kamerki i wrzuca ją do katalogu przy użyciu mechanizmu rotacyjnego.
Inny skrypt PHP przeszukuje katalog i wyświetla wszystkie obrazy JPG pasujące do wzorca nazwy w formacie tabelki obrazków. Dodatkowo codziennie o 22:00 inny skrypt używając mencoder’a łączy te JPG-i i tworzy wideo, niejako tworząc przyspieszony obraz wydarzeń z całego dnia rejestrowania kamery.

Skrypt wyciągający JPG-i z deamona MJPG-streamer:

#!/bin/bash

#gets image from webcam served and saves it into first param
function shot()
{
        /usr/bin/curl "http://localhost:3000/?action=snapshot" -o $1 2>/dev/null;
}

#check if webcam server(mjpg-stream) is running; quit if not
pgrep mjpg_streamer 1>/dev/null; [ $? != 0 ] &amp;&amp; exit 1;

#maximum number of pictures to take, if exceed - start from 0
pic_num=144;
#where the pics are stored
cd /var/www/localhost/htdocs/webcamgallery/
#set permissions accordingly
umask -S o+r 1>/dev/null;

#set current picture name accordingly
line=`/bin/ls *current* 2>/dev/null | /usr/bin/gawk 'BEGIN { FS="-";} /current/ { printf("%s %i out-current-%i-.jpg out-%i.jpg out-%i.jpg", $0, $3, ($3 + 1) > '$pic_num' ? 0 : ($3 + 1), $3, ($3 + 1) > '$pic_num' ? 0 : ($3 + 1) ); }' -`;

#make screenshot
if [ "$line" == "" ]; then
        #echo bummer!
        shot "out-current-0-.jpg";
fi

#format variables
set -- ${line#*:}; current=$1 num=$2 new_current=$3 old_current=$4 kwas=$5;

#move current image to old current and new pic shot to current
mv -f $current $old_current 2>/dev/null;
mv -f $kwas $new_current 2>/dev/null;

shot $new_current;

To natomiast jest skrypt robiący film(y) z obrazków JPG:

#!/bin/bash

#go to images location
cd /var/www/localhost/htdocs/webcamgallery;
j=0;

#make poster from 1st image and change other out*jpg images names to new*.jpg
for file in `ls -tr out*jpg`; do
if [ "$j" == "0" ]; then
/bin/cp -f $file poster.jpeg;
fi
/bin/cp -f $file `printf "new-%03d.jpg" $j`; j=$((j+1));
done;

#make WebM video from new* images
mencoder mf://new*.jpg -mf w=640:h=480:fps=15:type=jpg -really-quiet -nosound -ovc lavc -ffourcc VP80 -of lavf -lavfopts format=webm -lavcopts vcodec=libvpx -o video.webm

#make video.mp4 video fro flash from new*images
ffmpeg -y -i new-%03d.jpg -vcodec libx264 -level 41 -crf 25 -bufsize 20000k -maxrate 25000k -g 250 -r 20 -s 640x480 -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -subq 7 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -rc_eq 'blurCplx^(1-qComp)' -bf 16 -b_strategy 1 -bidir_refine 1 -refs 6 -deblockalpha 0 -deblockbeta 0 -v 0 -loglevel quiet video.mp4 2&amp;amp;amp;amp;gt; /dev/null

#set permissions
chmod 644 video.webm video.mp4 poster.jpeg
#remove unneccessary new images - cleanup
rm -f new*jpg

Dodatkowo jest jeszcze trochę kodu PHP który wyświetla zrzuty JPGów z całego dnia w tabelaryczny i uporządkowany sposób ale nie ma sensu tego pokazywać.

Końcowy efekt można podziwiać tu: http://haos.hopto.org/webcamgallery/

Jaki jest mój IP?

Zadanie: szybki hack na sprawdzanie okresowe adresu IP na zewnętrznym interfejsie routera.

Czytaj więcej »