Aynı soket üzerinde göndermek / almak için paralel çağrılar geçerli midir?


127
  1. Aynı soket üzerinde bir iş parçacığından gönder ve diğerinden geri çağırabilir miyiz?
  2. Aynı soket üzerindeki farklı evrelerden birden fazla gönderimi paralel olarak çağırabilir miyiz?

İyi bir tasarımın bundan kaçınması gerektiğini biliyorum, ancak bu sistem API'lerinin nasıl davranacağı konusunda net değilim. Aynı şekilde de iyi bir belge bulamıyorum.

Yöndeki herhangi bir işaret yardımcı olacaktır.


3
neden böyle yapmanın kötü bir uygulama olduğunu iddia ediyorsunuz? Bana güzel görünüyor çünkü farklı konulardan dinliyor ve alıyor.
TheMathNoob

Yanıtlar:


92

POSIX, gönderme / geri alma işlemini atomik işlemler olarak tanımlar, bu nedenle POSIX gönderme / alma hakkında konuştuğunuzu varsayarsak, evet, bunları birden çok iş parçacığından aynı anda çağırabilirsiniz ve işler çalışacaktır.

Bu, bunların paralel olarak yürütüleceği anlamına gelmez - birden fazla gönderme durumunda, ikincisi muhtemelen ilk tamamlanana kadar bloke olacaktır. Verilerini soket arabelleğine koyduktan sonra gönderme tamamlandığı için muhtemelen bu kadarını fark etmeyeceksiniz.

SOCK_STREAM soketlerini kullanıyorsanız, gönder / recv bir mesajın sadece bir kısmını gönderip alabileceğinden, bir şeyleri paralel yapmaya çalışmanın yararlı olma olasılığı daha düşüktür, bu da işlerin bölünebileceği anlamına gelir.

SOCK_STREAM soketlerinde gönderme / geri alma işleminin engellenmesi, yalnızca en az 1 bayt gönderip alınana kadar bloke edilir, bu nedenle engelleme ve engellememe arasındaki fark kullanışlı değildir.


1
@Joao: SOCK_DGRAM soketi "mesaj sınırlarının korunması" olarak belgelenmiştir, bu çok açık değildir. Linux çekirdeği kaynaklarına bakıldığında, en azından her gönderme ve geri alma işleminin tek bir paketle atomik olarak (en azından udp için) ilgilendiğini görebilirsiniz.
Chris Dodd

2
@Kedar: Ne demek istediğinden emin değilim. sendVeriler gönderme arabelleğine yerleştirilir yerleştirilmez bir geri döner ve veriler netowrk yığını aracılığıyla ve eşzamansız olarak ağa gönderilir. Dolayısıyla, bir iş parçacığına ve bir iş parçacığına sahipseniz, alıcı evre ilk paketi almadan önce gönderen iş parçacığının birçok paket göndermesi tamamen mümkündür (hatta olasıdır). Tamamen eşzamansız ve eşzamanlı değil.
Chris Dodd

6
@ChrisDodd, "POSIX gönderme / alma işlemini atomik işlemler olarak tanımlar" için bir bağlantı verebilir misiniz?
suitianshi

2
@suitianshi: POSIX 1003.1c standart belgesi, 1003.1'deki evresel (evrelerden aramak güvenli) olan ve olmayan tüm işlevleri listeler. Maalesef, ücretsiz bir çevrimiçi kopya bulabileceğimi bilmiyorum.
Chris Dodd

2
@ChrisDodd Kopyayı unix-systems.org/version4 üzerinde buldum ve Bölüm 7.1'de Sistem Arayüz Tablosu'nun listesini görebiliyorum, ancak atomik işlemler olarak fonksiyonları nerede listelediğini göremiyorum. Sizden şüphe etmeyin, ancak belgedeki amacınızı haklı çıkarmak için lütfen cevabınızı paylaşabilir / düzenleyebilir misiniz?
user153882

17

Soket tanımlayıcısı belirli bir evreye değil sürece aittir. Bu nedenle, farklı evrelerde aynı sokete / soketten gönderme / alma mümkündür, işletim sistemi senkronizasyonu yönetecektir.

Bununla birlikte, gönderme / alma sırası anlamsal olarak önemliyse, sizin (sırasıyla kodunuz) farklı iş parçacıklarındaki işlemler arasında uygun sıralamayı sağlamanız gerekir - iş parçacıklarında her zaman olduğu gibi.


4

Paralel olarak almanın nasıl bir şey başarabileceğini anlamıyorum. 3 baytlık bir mesajınız varsa, 1 iş parçacığı ilk 2 baytı ve bir diğeri son baytı alabilir, ancak hangisinin hangisi olduğunu söyleyemezsiniz. Mesajlarınız yalnızca bir bayt uzunluğunda olmadıkça, birden fazla iş parçacığı alındığında herhangi bir şeyi güvenilir bir şekilde çalıştırmanın bir yolu yoktur.

Birden çok gönderme olabilirTüm mesajı tek bir aramada gönderdiyseniz yarayabilir, ancak emin değilim. Birinin diğerinin üzerine yazması mümkündür. Bunu yapmanın kesinlikle herhangi bir performans faydası olmayacaktır.

Birden fazla iş parçacığının gönderilmesi gerekiyorsa, senkronize bir mesaj kuyruğu uygulamanız gerekir. Kuyruktaki iletileri okuyan ve diğer iş parçacıklarının tüm iletileri sıraya koymasını sağlayan gerçek gönderimi yapan bir iş parçacığına sahip olun. Aynı şey alma için de işe yarar, ancak alma iş parçacığı mesajların biçimini bilmek zorunda kalacak, böylece onları doğru bir şekilde serileştirebilsin.


9
SOCK_DGRAM soketlerini kullanıyorsanız, her bir recv tek bir datagram alır; recv'ler arasında asla bölünmeyecek
Chris Dodd

2
@noah, paralel kayıtların hiçbir şeyi başaramayacağına katılıyorum. Bu yüzden sormadım. Benim sorum paralel olarak gönder / geri al ve ardından birden çok gönderme paralel olarak. Cevabınız paralel gönderimler hakkında fikir veriyor. Aynısı için teşekkürler.
Jay

1
@Chris iyi nokta. TCP olduğunu varsayıyordum. @Jay Paralel olarak almak istediğiniz gibi "Gönder / geri çağırmayı paralel olarak arayabilir miyiz" sorusunu netleştirebilirsiniz.
noah
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.