- Bisakah kita memanggil kirim dari satu utas dan menerima dari yang lain pada soket yang sama?
- Bisakah kita memanggil banyak pengiriman secara pararel dari utas berbeda pada soket yang sama?
Saya tahu bahwa desain yang baik harus menghindari ini, tetapi saya tidak jelas bagaimana perilaku sistem API ini. Saya tidak dapat menemukan dokumentasi yang bagus juga untuk hal yang sama.
Setiap petunjuk arah akan membantu.
c
networking
sockets
Jay
sumber
sumber
Jawaban:
POSIX mendefinisikan send / recv sebagai operasi atom, jadi dengan asumsi Anda berbicara tentang POSIX send / recv maka ya, Anda dapat memanggil mereka secara bersamaan dari beberapa utas dan semuanya akan berfungsi.
Ini tidak berarti bahwa mereka akan dieksekusi secara paralel - dalam kasus beberapa pengiriman, yang kedua kemungkinan akan diblokir sampai yang pertama selesai. Anda mungkin tidak akan melihat sebanyak ini, karena pengiriman selesai setelah memasukkan datanya ke dalam buffer socket.
Jika Anda menggunakan soket SOCK_STREAM, mencoba melakukan hal-hal yang paralel cenderung tidak berguna karena mengirim / menerima mungkin mengirim atau menerima hanya sebagian dari pesan, yang berarti berbagai hal dapat terpecah.
Memblokir send / recv pada soket SOCK_STREAM hanya memblokir sampai mereka mengirim atau menerima setidaknya 1 byte, sehingga perbedaan antara pemblokiran dan non-pemblokiran tidak berguna.
sumber
send
pengembalian segera setelah data ditempatkan ke dalam mengirim buffer, dan data dikirim pada melalui tumpukan netowrk dan keluar ke jaringan asynchronous. Jadi, jika Anda memiliki satu utas pengiriman dan satu utas penerima, sangat mungkin (bahkan mungkin) utas utas untuk mengirim banyak paket sebelum utas penerima menerima paket pertama. Sepenuhnya asinkron dan tidak simultan.Deskriptor soket milik proses, bukan ke utas tertentu. Oleh karena itu, dimungkinkan untuk mengirim / menerima ke / dari soket yang sama di utas yang berbeda, OS akan menangani sinkronisasi.
Namun, jika urutan pengiriman / penerimaan adalah signifikan secara semantik, Anda sendiri (masing-masing kode Anda) harus memastikan urutan yang benar antara operasi di utas berbeda - seperti yang selalu terjadi pada utas.
sumber
Saya tidak melihat bagaimana menerima secara paralel dapat mencapai apa pun. Jika Anda memiliki pesan 3 byte, 1 utas dapat memperoleh 2 byte pertama dan satu lagi byte terakhir, tetapi Anda tidak memiliki cara untuk mengetahui yang mana. Kecuali jika pesan Anda panjangnya hanya satu byte, tidak mungkin Anda dapat andal membuat apa pun dengan menerima banyak utas.
Beberapa pengiriman mungkin berhasil, jika Anda mengirim seluruh pesan dalam satu panggilan, tetapi saya tidak yakin. Mungkin saja satu bisa menimpa yang lain. Tentu tidak akan ada manfaat kinerja untuk melakukannya.
Jika beberapa utas perlu dikirim, Anda harus menerapkan antrian pesan yang disinkronkan. Memiliki satu utas yang melakukan pengiriman aktual yang membaca pesan dari antrean dan utas lainnya enqueue seluruh pesan. Hal yang sama akan berfungsi untuk menerima, tetapi utas penerima harus mengetahui format pesan sehingga dapat membatalkan deserialisasi dengan benar.
sumber