gniazda domeny unix VS nazwane potoki?

122

Po obejrzeniu unixa o nazwie socket i pomyślałem, że to potoki. Spojrzałem na nazwy rur i nie zauważyłem dużej różnicy. Widziałem, że zostały zainicjowane inaczej, ale to jedyna rzecz, jaką zauważyłem. Oba używają funkcji zapisu / odczytu C i działają podobnie AFAIK.

Jaka jest różnica między gniazdami domeny unix a nazwanymi potokami? Kiedy wybrałbym jedną z nich? Którego powinienem używać domyślnie (na przykład jak domyślnie używam vector w C ++ niż używam deque, list lub cokolwiek innego, jeśli mam potrzeby)?


źródło
1
@GregHewgill: niestety to pytanie dotyczy bardziej „czym jest IPC” niż różnicy, o którą pytam: /. Widziałem to przed wysłaniem, czy powinienem był dodać link i powiedzieć, że jest to powiązane? (nie było to dla mnie pomocne)
1
@acid: Tak, łączenie powiązanych pytań i wyjaśnianie pytania, które nadal masz, jest zawsze dobrym pomysłem.
Ben Voigt
3
Ten artykuł podsumował to dobrze. Demystifying Unix Domain Sockets: thomasstover.com/uds.html
Cong Ma
Uszkodzony link: techdeviancy.com/uds.html
mcdado

Odpowiedzi:

106

Gniazda domeny UNIX są generalnie bardziej elastyczne niż potoki nazwane. Niektóre z ich zalet to:

  • Można ich używać dla więcej niż dwóch procesów komunikujących się (np. Proces serwera z potencjalnie wieloma łączącymi się procesami klienta);
  • Są dwukierunkowe;
  • Obsługują przekazywanie poświadczeń UID / GID zweryfikowanych przez jądro między procesami;
  • Obsługują przekazywanie deskryptorów plików między procesami;
  • Obsługują tryby pakietowe i sekwencyjne.

Aby użyć wielu z tych funkcji, musisz użyć send()/ recv()rodzina wywołań systemowych zamiast write()/ read().

kawiarnia
źródło
11
Z drugiej strony, należałoby być może powiedzieć, że potoki nazw mają tę zaletę, że można je „łączyć” przez zwykłe open(2)wywołania, co czyni je bardziej odpowiednimi do konstruowania potoków ad-hoc między programami, które zwykle pobierają tylko argumenty nazw plików.
Dolda2000
66

Jedyną różnicą jest to, że nazwane potoki są jednokierunkowe, więc do komunikacji dwukierunkowej musisz użyć dwóch z nich. Gniazda są oczywiście dwukierunkowe. Używanie dwóch zmiennych zamiast jednej (czyli dwóch rur zamiast jednego gniazda) wydaje się nieco bardziej skomplikowane.

Ponadto artykuł w Wikipedii jest dość jasny w następującym punkcie : „Gniazda domeny uniksowej mogą być tworzone jako strumienie bajtów lub jako sekwencje datagramów, podczas gdy potoki są tylko strumieniami bajtów”.


Nazwane potoki są w rzeczywistości dwukierunkowe, ale półdupleksowe . Oznacza to, że komunikacja może przebiegać albo od końca A do końca B, albo od B do A, ale nigdy w tym samym czasie.

jtoberon
źródło
1
hmm ciekawe +1. Czy przypadkiem wiesz, jaka jest różnica między strumieniem bytestream a datagramem? Może na przykład w zdaniu lub dwóch, jak już zrobiłeś na to pytanie?
7
@acidzombie: Potok lub gniazdo w trybie datagramowym zachowuje granice, więc jedno writewywołanie generuje jedno readwywołanie. W trybie strumieniowym dane mogą być łączone razem w jeden długi strumień, dzięki czemu można odczytać wiele zapisów jednocześnie lub odwrotnie. (Windows ma potoki datagramowe, zgodnie z odpowiedzią jtoberona, Unix nie)
Ben Voigt,
1
@BenVoigt No cóż, dostarczanie pakietów przez gniazdo datagramowe jest zawodne, więc zapis niekoniecznie generuje wywołanie odczytu. Być może dla lokalnych gniazd, ale nie wynika to jasno z twojego komentarza. Więc niezależnie od tego ma problemy.
xaxxon
3
@xaxxon: Zarówno potoki, jak i gniazda domeny unix lokalne, więc odbiorca w ogóle opróżnia swoje kolejki bez strat.
Ben Voigt
6
Tak, w przeciwieństwie do UDP, gniazda datagramowe domeny Unix są gwarantowane , dostawa na zamówienie.
jtchitty