2012-06-09 22 views
5

Uzak bir ana bilgisayara bir soket bağlantısı yapmayı deneyen pthread ortaya çıkan bazı kodlarım var. Bağlantı hiç kaybolursa, soketinde connect() numaralı bir engellemeyi kullanarak yeniden bağlanmayı dener. Kod ayrı bir iş parçacığı içinde çalıştığı için, eşzamanlı soket API'sini kullanması gerçekten umrumda değil.Engelleme soketini gerçekleştiren bir iş parçacığı nasıl bağlanır?

Uygulamamın çıkma zamanı gelene kadar. Düzenli bir kapanışın bazı yanlarını gerçekleştirmek istiyorum, bu yüzden iş parçacığı uyanmak için iş parçacığı eşitleme ilkelerini kullanın ve çıkması için sinyal verin, sonra iş parçacığı üzerinde tamamlamak için beklemek için bir pthread_join() gerçekleştirin. Bu kilitleme komutunu verdiğimde, iş parçacığı bir connect() aramanın ortasında değilse harika çalışıyor. Bu durumda, bağlantıyı zaman aşımına uğratmak zorundayım, bu da uzun bir zaman olabilir. Bu, uygulamanın kapatılması uzun sürüyor gibi görünüyor.

Yapmak istediklerim, bir şekilde connect() aramasına aramayı kesmektir. Çağrı geri döndükten sonra, iş parçacığı çıkış sinyalimi fark edecek ve temiz bir şekilde kapanacaktır. connect() bir sistem çağrısı olduğundan, bir sinyal kullanarak kasıtlı olarak kesebileceğimi düşündüm (bu nedenle EINTR numaralı çağrıyı geri döndürür), ancak POSIX iş parçacıklarında sağlam bir yöntem olup olmadığından emin değilim.

Sinyalleri veya başka bir yöntem kullanarak, bunun nasıl yapılacağı konusunda herhangi bir önerisi var mı? Bir not olarak, connect() çağrısı bazı kütüphane kodlarında değiştiremediğim için, engelleme olmayan bir yuvaya geçmek bir seçenek değildir.

+2

Lütfen ayrıca bir dil etiketi koyun. – Tudor

+0

Aslında Python'da yazıyorum, ama dile özgü hiçbir şey aramıyorum. Linux üzerinde çalıştığımı varsayabilirsin. –

+1

Soketi kapatın. –

cevap

6

deneyin için close() soket () bağlamak kesmek. Emin değilim, ama en azından Linux üzerinde çalışacağını düşünüyorum. Tabii ki, düzgün bir şekilde yakın() bu soketi bir kez ya da bir close()'un yeni açılmış olan bir dosya tanımlayıcısını teorik olarak kapatabilirsiniz.

DÜZENLEME: aslında soket kapatmadığı için kapatma() daha uygun olabilir.

Alternatif olarak, pthread_cancel() ve pthread_kill()'a bakmak isteyebilirsiniz. Ancak, bu ikisini yarış durumu olmadan kullanmanın bir yolunu görmüyorum.

Çok işlemcili sunucu yaklaşımını terk etmenizi ve etkinlik bildirimi için örneğin epoll'u kullanarak olaya dayalı gitmenizi tavsiye ederim. Bu şekilde, uygun kapatma gibi iş parçacıkları ile çok zor hale gelen tüm bu çok temel sorunları önleyebilirsiniz. İstediğiniz zaman herhangi bir anda yapmakta özgürsünüz, ör. Soketleri güvenli bir şekilde kapatın ve bir daha asla onlardan haber alamazsınız. Öte yandan

, sizin çalışan iş parçacığı bir (veya)() ( bağlayıp epoll_pwait yoluyla haberdar olsun engellenmeyen ppoll yaparsanız() veya pSELECT(); p not), sinyallerle ilgili yarış koşullarından kaçınabilirsiniz.

+0

'close()' kullanma önerisi için teşekkürler; Buna bakacağım. Bir olaya dayalı mekanizmanın daha iyi olacağını kabul ediyorum.Ancak, benim soruda belirttiğim gibi, "connect()" çağrısı, değiştiremediğim bazı kütüphane kodlarında aşağıdayken, engelleme olmayan bir sokete geçmek bir seçenek değildir. " –

+0

"Değiştirilemiyor" kısmı burada büyük bir sorun olmalı. Dikkat ettiğim gibi, iki kez kapanmamaya dikkat edin; Kütüphane connect() geri döndükten sonra onu kapatmak isteyebilir. Tüm malzemeleriniz bittiğinde zorla süreci sona erdirmeyi düşündünüz mü, bu durumda, işgalci kodun bu noktaya kadar yanlış davranmadığından emin olmak ister misiniz? –

+2

'shutdown()' işlevini kullanmaya başladım. Kütüphane Python'da yazıldığından, göz atabilir ve alttaki sokete erişebilir ve daha sonra kapatılabilir. İyi çalışıyor. Yazılım mimarisi açısından en iyi yaklaşım değil, ama burada çalışıyor ve kullanılacak kütüphanenin sürümü üzerinde kontrolüm var. –

İlgili konular