VoIP motor Mediastreamer2 tanulmånyozåsa. 12. rész

A cikk anyaga az én Dzen csatornåmból szårmazik.

VoIP motor Mediastreamer2 tanulmånyozåsa. 12. rész

A mĂșltban a Spotify döntĂ©shozatali mĂłdszertanĂĄrĂłl. Egyre több felhasznĂĄlĂł preferĂĄlja a zenehallgatĂĄst mobilon a streaming szolgĂĄltatĂĄsban, de a cĂ©gnĂ©l tĂșlnyomĂłrĂ©szt webprogramozĂłk dolgoznak. A Spotify elemezte ezt a helyzetet, Ă©s Ășgy döntött, hogy több mobilfejlesztƑt vesz fel, valamint ĂĄtnevezi a webes szakembereket Ășj irĂĄnyba:, megĂ­gĂ©rtem, hogy foglalkozom a terhelĂ©sĂ©rtĂ©kelĂ©s kĂ©rdĂ©sĂ©vel a ticker esetĂ©ben, Ă©s a tĂșlzott szĂĄmĂ­tĂĄsi terhelĂ©s kezelĂ©sĂ©nek mĂłdjaival a mĂ©diastreamerben. De Ășgy döntöttem, logikusabb lesz elƑször a kraft szƱrƑk hibakeresĂ©si kĂ©rdĂ©seit bemutatni, amelyek az adatok ĂĄthelyezĂ©sĂ©vel kapcsolatosak, Ă©s csak ezt követƑen foglalkozni a teljesĂ­tmĂ©nyoptimalizĂĄlĂĄs kĂ©rdĂ©seivel.

A kraft szƱrƑk hibakeresĂ©se

MiutĂĄn a korĂĄbbi cikkben ĂĄttekintettĂŒk az adatok ĂĄthelyezĂ©sĂ©nek mechanizmusĂĄt a mĂ©diastreamerben, logikus lenne beszĂ©lni az abban rejlƑ veszĂ©lyekrƑl. Az "adata ĂĄramlĂĄsa" elv egyik sajĂĄtossĂĄga, hogy a memĂłria kiemelĂ©se a halombĂłl azokban a szƱrƑkben törtĂ©nik, amelyek az adatfolyam kezdetĂ©n helyezkednek el, mĂ­g a memĂłria felszabadĂ­tĂĄsa, vissza a halomba, mĂĄr a folyamat vĂ©gĂ©n talĂĄlhatĂł szƱrƑk ĂĄltal törtĂ©nik. Ezen kĂ­vĂŒl az Ășj adatok lĂ©trehozĂĄsa Ă©s megsemmisĂ­tĂ©se valahol a köztes pontokban is elƑfordulhat. ÁltalĂĄnos esetben a memĂłria felszabadĂ­tĂĄsĂĄt nem az a szƱrƑ vĂ©gzi, amelyik lĂ©trehozta az adatblokkot.

A memĂłria ĂĄtlĂĄthatĂł nyomon követĂ©se szempontjĂĄbĂłl Ă©sszerƱ lenne, ha a szƱrƑ, miutĂĄn megkapta a bemeneti blokkjĂĄt, azonnal megsemmisĂ­tenĂ© azt a feldolgozĂĄs utĂĄn a memĂłria felszabadĂ­tĂĄsĂĄval, Ă©s a kimeneten egy Ășjonnan lĂ©trehozott blokkot helyezne el a kimeneti adatokkal. Ebben az esetben a memĂłria szivĂĄrgĂĄsa a szƱrƑben könnyen nyomon követhetƑ lenne — ha az elemzƑ szivĂĄrgĂĄst Ă©szlel a szƱrƑben, akkor a következƑ szƱrƑ nem semmisĂ­ti meg megfelelƑen a bejövƑ blokkokat, ami hiba lenne benne. De a magas teljesĂ­tmĂ©ny fenntartĂĄsa szempontjĂĄbĂłl ez a megközelĂ­tĂ©s a dolgokkal valĂł munkĂĄra nem produktĂ­v — ez nagyszĂĄmĂș mƱvelethez vezet a memĂłria kiemelĂ©sĂ©re/felszabadĂ­tĂĄsĂĄra az adatblokkok szĂĄmĂĄra, bĂĄrmilyen hasznos kimenet nĂ©lkĂŒl.

EzĂ©rt a mĂ©diastreamer szƱrƑk, hogy ne lassĂ­tsĂĄk az adatok feldolgozĂĄsĂĄt, ĂŒzenetek mĂĄsolĂĄsakor olyan funkciĂłkat hasznĂĄlnak, amelyek könnyƱ mĂĄsolatokat hoznak lĂ©tre (errƑl az elƑzƑ cikkĂŒnkben Ă­rtunk). Ezek a funkciĂłk csak Ășj ĂŒzenetfejlĂ©c pĂ©ldĂĄnyt hoznak lĂ©tre, "rögzĂ­tve" hozzĂĄ a mĂĄsolt "rĂ©gi" ĂŒzenet adatblokkot. Ennek eredmĂ©nyekĂ©nt egy adatblokkhoz kĂ©t fejlĂ©c kapcsolĂłdik, Ă©s a hivatkozĂĄsi szĂĄmlĂĄlĂł az adatblokkban növekszik. De ez Ășgy fog kinĂ©zni, mint kĂ©t ĂŒzenet. Az ilyen "megosztott" adatblokkal rendelkezƑ ĂŒzenetek szĂĄma lehet több is, pĂ©ldĂĄul az MS_TEE szƱrƑ egyszerre több ilyen könnyƱ mĂĄsolatot generĂĄl, amelyeket a kimenetei között oszt el. Minden szƱrƑ megfelelƑ mƱködĂ©se mellett a csƑ vĂ©gĂ©n ennek a hivatkozĂĄsi szĂĄmlĂĄlĂłnak nullĂĄra kell csökkennie, amelyet a memĂłriafelszabadĂ­tĂł funkciĂł hĂ­v meg: ms_free(). Ha a hĂ­vĂĄs nem törtĂ©nik meg, akkor ez a memĂłria mĂĄr nem tĂ©rhet vissza a halomba, azaz "szivĂĄrogni" fog. A könnyƱ mĂĄsolatok hasznĂĄlatĂĄnak ĂĄra az a lehetƑsĂ©g elvesztĂ©se, hogy könnyen megĂĄllapĂ­tsuk (ahogy az normĂĄl mĂĄsolatokkal lett volna), hogy mely szƱrƑ grafikonban szivĂĄrog a memĂłria.

Mivel a memĂłria szivĂĄrgĂĄsok keresĂ©sĂ©nek felelƑssĂ©ge a "natĂ­v" szƱrƑkben a mĂ©diastreamer fejlesztƑinĂ©l van, valĂłszĂ­nƱleg nem kell Ƒket hibakeresni. De a sajĂĄt kĂ©szĂ­tĂ©sƱ szƱrƑddel – te vagy a sajĂĄt boldogsĂĄgod kovĂĄcsa, Ă©s a te precizitĂĄsodtĂłl fĂŒgg, mennyi idƑt töltesz el a hibĂĄk keresĂ©sĂ©vel a kĂłdodban. Az idƑd letartĂłztatĂĄsĂĄnak csökkentĂ©se Ă©rdekĂ©ben meg kell vizsgĂĄlnunk a memĂłria szivĂĄrgĂĄsok lokalizĂĄlĂĄsĂĄnak mĂłdszereit a szƱrƑk fejlesztĂ©sekor. EzenkĂ­vĂŒl elƑfordulhat, hogy a szivĂĄrgĂĄs csak akkor nyilvĂĄnul meg, amikor a szƱrƑt egy valĂłs rendszerben alkalmazzĂĄk, ahol a "gyanĂșsĂ­tottak" szĂĄma hatalmas lehet, Ă©s a hibakeresĂ©sre szĂĄnt idƑ korlĂĄtozott.

Hogyan mutatkozik meg a memĂłria szivĂĄrgĂĄs?

Logikus feltĂ©telezni, hogy a program kimenetĂ©ben top a memĂłria folyamatosan növekvƑ szĂĄzalĂ©ka fog megjelenni, amelyet az alkalmazĂĄsod foglal el.

A kĂŒlsƑ megnyilvĂĄnulĂĄs abban ĂĄll majd, hogy a rendszer egy idƑ utĂĄn lassan reagĂĄl a mouse mozgĂĄsĂĄra, lassan frissĂ­ti a kĂ©pernyƑt. ElƑfordulhat, hogy a rendszer naplĂłja is nƑni fog, ezzel helyet foglalva a merevlemezen. Eközben az alkalmazĂĄsod furcsa mĂłdon fog viselkedni, nem reagĂĄl a parancsokra, nem tud fĂĄjlt megnyitni, stb.

A szivĂĄrgĂĄs megĂĄllapĂ­tĂĄsĂĄhoz memĂłriaelemzƑt (a tovĂĄbbiakban: elemzƑ) fogunk hasznĂĄlni. Ez lehet Valgrind (jĂł cikk errƑl) vagy a fordĂ­tĂłba beĂ©pĂ­tett gcc MemorySanitizer vagy valami mĂĄs. Ha az elemzƑ azt mutatja, hogy a szivĂĄrgĂĄs egy grafikon egyik szƱrƑjĂ©ben törtĂ©nik, az azt jelenti, hogy itt az ideje alkalmazni az alĂĄbb leĂ­rt mĂłdszerek egyikĂ©t.

A hĂĄrom szƱrƑ mĂłdszere

Ahogy korĂĄbban emlĂ­tve lett, szivĂĄrgĂĄs esetĂ©n az elemzƑ arra a szƱrƑre mutat, amely a memĂłriĂĄt igĂ©nyelte a halombĂłl. De nem fogja megmutatni azt a szƱrƑt, amely "elfelejtette" visszaadni, amely valĂłjĂĄban a hibĂĄs. Így az elemzƑ csak megerƑsĂ­theti a gyanĂșnkat, de nem mutatja meg annak gyökerĂ©t.

A "rossz" szƱrƑ helyĂ©nek meghatĂĄrozĂĄsĂĄhoz a grafikon minimalizĂĄlĂĄsĂĄnak lehetsĂ©ges ĂștjĂĄt követhetjĂŒk, hogy a lehetƑ legkisebb csomĂłpontoknĂĄl az elemzƑ mĂ©g mindig Ă©szleli a szivĂĄrgĂĄst, Ă©s a megmaradt hĂĄrom szƱrƑn belĂŒl lokalizĂĄljuk a problĂ©mĂĄs szƱrƑt.

De elƑfordulhat, hogy a grafikon szƱrƑinek szĂĄmĂĄnak csökkentĂ©sekor megszakĂ­tod a szƱrƑk normĂĄl kölcsönhatĂĄsĂĄt a rendszered többi elemĂ©vel, Ă©s a szivĂĄrgĂĄs mĂĄr nem mutatkozik meg. Ebben az esetben a teljes mĂ©retƱ grafikonon kell dolgozni, Ă©s az alĂĄbb ismertetett megközelĂ­tĂ©st kell alkalmazni.

A mozgó szigetelƑ módszere

A magyarĂĄzat egyszerƱsĂ­tĂ©se Ă©rdekĂ©ben egy olyan grafikonnal fogunk dolgozni, amely egy szƱrƑlĂĄncbĂłl ĂĄll. Ez a rajzon lĂĄthatĂł.

VoIP motor Mediastreamer2 tanulmånyozåsa. 12. rész

Egy normĂĄl grĂĄf, amelyben a mĂ©diastreamer kĂ©sz szƱrƑi mellett nĂ©gy kĂ©zmƱves szƱrƑ van F1
F4, nĂ©gy kĂŒlönbözƑ tĂ­pustĂłl, amelyeket rĂ©gen kĂ©szĂ­tettĂ©l, Ă©s biztos vagy a helyessĂ©gĂŒkben. MindazonĂĄltal feltĂ©telezzĂŒk, hogy ezek közĂŒl nĂ©hĂĄnyban memĂłria szivĂĄrgĂĄs van. A programunk futtatĂĄsĂĄval, amely a figyelƑ elemzƑt hasznĂĄlja, az abbĂłl szĂĄrmazĂł jelentĂ©sbƑl megtudjuk, hogy egy bizonyos szƱrƑ kĂ©rt egy bizonyos mennyisĂ©gƱ memĂłriĂĄt, Ă©s azt nem adta vissza a heap-be N darabszor. Könnyen kitalĂĄlhatĂł, hogy a hivatkozĂĄs a MS_VOID_SOURCE tĂ­pusĂș szƱrƑ belsƑ funkciĂłira mutat. Ennek feladata az, hogy memĂłriĂĄt vegyen el a heap-bƑl. Azt mĂĄs szƱrƑknek kell visszaadniuk. TehĂĄt Ă©szleljĂŒk a szivĂĄrgĂĄs tĂ©nyĂ©t.

Annak meghatĂĄrozĂĄsĂĄra, hogy a gyĂĄrtĂłsor mely szakaszĂĄn törtĂ©nt az a tĂ©tlensĂ©g, amely memĂłria szivĂĄrgĂĄshoz vezetett, javasolt egy tovĂĄbbi szƱrƑt bevezetni, amely egyszerƱen ĂĄtkonvertĂĄlja az ĂŒzeneteket a bemenetrƑl a kimenetre, viszont lĂ©trehoz egy nem könnyƱ, hanem normĂĄlis "nehĂ©z" mĂĄsolatot a bemeneti ĂŒzenetrƑl, majd teljesen eltĂĄvolĂ­tja a bemenetre Ă©rkezƑ ĂŒzenetet. Ezt a szƱrƑt izolĂĄtornak nevezzĂŒk. FeltĂ©telezzĂŒk, hogy mivel a szƱrƑ egyszerƱ, ezĂ©rt benne a szivĂĄrgĂĄs kizĂĄrt. Egy mĂĄsik pozitĂ­v tulajdonsĂĄga pedig, hogy ha bĂĄrmelyik helyre beillesztjĂŒk a grĂĄfunkba, az nem befolyĂĄsolja a sĂ©ma mƱködĂ©sĂ©t. Az izolĂĄlĂł szƱrƑt dupla kerĂŒletƱ körkĂ©nt ĂĄbrĂĄzoljuk.

Az izolĂĄtort azonnal a voidsource szƱrƑ utĂĄn kapcsoljuk be:
VoIP motor Mediastreamer2 tanulmånyozåsa. 12. rész

Újra elindĂ­tjuk a programot az elemzƑvel, Ă©s azt lĂĄtjuk, hogy ez alkalommal az elemzƑ az izolĂĄtort okolja. VĂ©gĂŒl is Ƒ hozza lĂ©tre azokat az adatblokkot, amelyek kĂ©sƑbb egy ismeretlen gondatlan szƱrƑ (vagy szƱrƑk) ĂĄltal elvesznek. A következƑ lĂ©pĂ©sben az izolĂĄtort egy szƱrƑvel jobbra mozgatjuk, Ă©s Ășjra elindĂ­tjuk az elemzĂ©st. TehĂĄt, lĂ©pĂ©srƑl lĂ©pĂ©sre jobbra mozgatva az izolĂĄtort, olyan helyzetet kapunk, amikor a következƑ elemzƑ jelentĂ©sben az "elhalvĂĄnyult" memĂłria blokkok szĂĄma csökken. Ez azt jelenti, hogy ezen a lĂ©pĂ©sen az izolĂĄtor a problĂ©mĂĄs szƱrƑ utĂĄn helyezkedett el a lĂĄncban. Ha a "rossz" szƱrƑ egyetlen volt, akkor a szivĂĄrgĂĄs teljesen eltƱnik. Így lokalizĂĄltuk a problĂ©mĂĄs szƱrƑt (vagy az egyik a több közĂŒl). A szƱrƑ "javĂ­tĂĄsa" utĂĄn folytathatjuk az izolĂĄtor jobbra mozgatĂĄsĂĄt a lĂĄncon, amĂ­g teljes mĂ©rtĂ©kben meg nem szĂŒntetjĂŒk a memĂłria szivĂĄrgĂĄsokat.

Az izolĂĄlĂł szƱrƑ implementĂĄlĂĄsa

Az izolĂĄtor megvalĂłsĂ­tĂĄsa Ășgy nĂ©z ki, mint egy normĂĄl szƱrƑ. FejlĂ©c:

/* ЀаĐčĐ» iso_filter.h  ĐžĐżĐžŃĐ°ĐœĐžĐ” ĐžĐ·ĐŸĐ»ĐžŃ€ŃƒŃŽŃ‰Đ”ĐłĐŸ Ń„ĐžĐ»ŃŒŃ‚Ń€Đ°. */

#ifndef iso_filter_h
#define iso_filter_h

/* Đ—Đ°ĐŽĐ°Đ”ĐŒ ĐžĐŽĐ”ĐœŃ‚ĐžŃ„ĐžĐșĐ°Ń‚ĐŸŃ€ Ń„ĐžĐ»ŃŒŃ‚Ń€Đ°. */
#include <mediastreamer2/msfilter.h>

#define MY_ISO_FILTER_ID 1024

extern MSFilterDesc iso_filter_desc;

#endif

A szƱrƑ:

/* ЀаĐčĐ» iso_filter.c  ĐžĐżĐžŃĐ°ĐœĐžĐ” ĐžĐ·ĐŸĐ»ĐžŃ€ŃƒŃŽŃ‰Đ”ĐłĐŸ Ń„ĐžĐ»ŃŒŃ‚Ń€Đ°. */

#include "iso_filter.h"

    static void
iso_init (MSFilter * f)
{
}
    static void
iso_uninit (MSFilter * f)
{
}

    static void
iso_process (MSFilter * f)
{
    mblk_t *im;

    while ((im = ms_queue_get (f->inputs[0])) != NULL)
    {
        ms_queue_put (f->outputs[0], copymsg (im));
        freemsg (im);
    }
}

static MSFilterMethod iso_methods[] = {
    {0, NULL}
};

MSFilterDesc iso_filter_desc = {
    MY_ISO_FILTER_ID,
    "iso_filter",
    "A filter that reads from input and copy to its output.",
    MS_FILTER_OTHER,
    NULL,
    1,
    1,
    iso_init,
    NULL,
    iso_process,
    NULL,
    iso_uninit,
    iso_methods
};

MS_FILTER_DESC_EXPORT (iso_desc)

MemĂłriakezelƑ fĂŒggvĂ©nyek helyettesĂ­tĂ©si metĂłdus

Finomabb kutatĂĄsokhoz a mĂ©diastreamer lehetƑsĂ©get biztosĂ­t a memĂłriĂĄhoz valĂł hozzĂĄfĂ©rĂ©s fĂŒggvĂ©nyeinek sajĂĄt magunk ĂĄltal törtĂ©nƑ helyettesĂ­tĂ©sĂ©re, amelyek alapvetƑ munkĂĄjukon tĂșl rögzĂ­tik, hogy "Ki, hova Ă©s miĂ©rt". HĂĄrom fĂŒggvĂ©ny kerĂŒl helyettesĂ­tĂ©sre. Ez a következƑkĂ©ppen törtĂ©nik:

OrtpMemoryFunctions reserv;
OrtpMemoryFunctions my;

reserv.malloc_fun = ortp_malloc;
reserv.realloc_fun = ortp_realloc;
reserv.free_fun = ortp_free;

my.malloc_fun = &my_malloc;
my.realloc_fun = &my_realloc;
my.free_fun = &my_free;

ortp_set_memory_functions(&my);

Ez a lehetƑsĂ©g hasznos, amikor az elemzƑ annyira lelassĂ­tja a szƱrƑk mƱködĂ©sĂ©t, hogy ez zavart okoz a rendszerben, amelybe a sĂ©mĂĄnk be van Ă©pĂ­tve. Ebben a helyzetben kĂ©nytelenek vagyunk lemondani az elemzƑrƑl, Ă©s a memĂłriakezelƑ fĂŒggvĂ©nyek helyettesĂ­tĂ©sĂ©t alkalmazni.

Megvizsgåltuk az eljåråsok algoritmusåt egy egyszerƱ gråf szåmåra, amely nem tartalmaz ågazåsokat. De ezt a megközelítést mås esetekre is alkalmazni lehet, persze bonyolultabb formåban, de az ötlet ugyanaz marad.

A következƑ cikkben a ticker terhelĂ©sĂ©nek Ă©rtĂ©kelĂ©sĂ©vel Ă©s a mĂ©diastreamerben jelentkezƑ tĂșlzott szĂĄmĂ­tĂĄsi terhelĂ©s kezelĂ©sĂ©nek mĂłdjaival foglalkozunk.

ForrĂĄs: habr.com

MegbĂ­zhatĂł hosting vĂĄsĂĄrlĂĄsa weboldalak szĂĄmĂĄra, DDoS vĂ©delemmel, VPS VDS szerverek. đŸ”„ MegbĂ­zhatĂł webtĂĄrhely vĂĄsĂĄrlĂĄsa DDoS vĂ©delemmel, VPS VDS szerverek | ProHoster