milisImageWriter


#1

Selamlar arkdaşlar, ben birkaç ay önce minikRıfkı projesini yapan arkadaşım. minikRıfkı daki hataları düzelttim. milisLinux a bi nebze olsun destek vermek istiyorum.

Bir üstad vardı, “pep standartlarına uy” demişti.
Üzgünüm, uyamadım, pep standartlarını bilmiyorum. Ama elimden geleni yaptım.

Son olarak, kimse test etmez belki ama, yine de sorayım.

Bu uygulamayı test edip hatam varsa lütfen belirtebilir misiniz? Bundan mutlu olacağım.

Bunun dışında her öneriye de açık insanım.

Projeyi gtk ile yaptım.

Sadece default branch e bakın, çünkü müsait bir vakitte diğer branchleri temizleyeceğim.

İyi günler dilerim hepinize.

Tabi bu proje sadece milis linux için değildir. Her türk projesine destek vermek isterim.

Derslerden pek kafamı kaldıramıyorum. O yüzden yazılım işleriyle üniversitesiteye kadar uğraşmayacağım. Hayırlı günler dilerim.

Projem:


#2

Elinize sağlık. Programı henüz denemedim ama gayet sade yazılmış. Peki 1096 bayt şeklinde okuyup yazmak biraz yavaş olmuyor mu büyük dosyalar için? Ya da standart bu şekilde mi acaba?


#3

Çok teşekkür ederim :slight_smile:

Aslında ben bu projeyi yaparken linux mint’in mintstick adlı programından ilham aldım. Haklısınız, linux mint’in projesinde 4096 bayt şeklinde okuyup yazar. Ama ben bunu yanlışlıkla 1096 bayt görüp yazdım.

Ama iyiki de böyle yapmışım, çünkü programdaki şu döngüye göre :

def run(self):
        print('e[32m'+"[ WriteThread ] -> is started"+'e[0m')
        try:
            while not self.cancel_event.isSet():
                if not self.state_event.isSet():
                    self.write()
            self.updatePosterSignal.emit("update",0.0, 0.0, 0.0)
        except:
            unknownErr = Dialogs("Unknown Error", self.window)
            response = unknownErr.run()
            if response == Gtk.ResponseType.OK:
                unknownErr.destroy()
        finally:
            self.sourceFileHandler.close()
            self.targetDeviceHandler.close()
                
        print('e[32m'+"[ WriteThread ] -> is closed"+'e[0m')

Buradaki asıl işlem:

[...]
            while not self.cancel_event.isSet():
                if not self.state_event.isSet():
                    self.write()
[...]

Eğer ben dosyayı 1096 bayt yerine 4096 bayt okusaydım, ben threadi öldürmek istediğimde thread daha geç ölecekti. Bu da benim işime gelmez.

Yani programın işini daha hızlı yapmasını herkes ister, ama hızlılıktan çok güvenliği amaçladım ben.

Güzel günler dilerim, takıldığınız yeri sorun.

Bu arada benim de bir sorum olacak:

Thread güvenliği açısından bir threadin öldüğünden emin olmak zorundayım ve bunun için join kullanmalıyım. Ama hard work iş yaptırdığım thread için join metodu gui de sıkıntı yaratıyor. Bunu nasıl halledebilirim? (Not: Aslında Gobject.idle_add metodu var-üstelik daha denemiş de değilim- ama ne işe yaradığını hala çözümleyebilmiş değilim.)


#4

Thread guvenliginden kasit nedir? Ne yapmaya calisiyorsun?

Neden join kullanmak zorundasin? Kullaninca GUI’de ne sikinti oluyor? Neyi nasil halledebilirsin?


#5

Ne kadar açık olabilirim acaba? Ben bu programda toplamda sadece 1 tane yazma işlemi yapan thread istiyorum. Yani bir programda 2 tane yazma işlemi yapan thread olursa tehlike doğar. Aslında böyle bir tehlike ihtimali yok, ama ben garantici bir insanım.

Çünkü join methodu,bir thread iş parçacığını ölünceye kadar bekler.

Uygulama cevap vermiyor.

Yapıcı bir dil kullanmaya çalışıyorum,ama dayanamayacağım, burada gayet açığım.

Kolay gelsin.


#6

Thread guvenligini programin neresinde istedigini soyleyerek baslayabilirsin mesela. Veya “butun programimda istiyorum lutfen” diyerek.

O zaman amacin “bir thread is parcacigini olunceye kadar beklemek” mi? Cunku eger amacin “thread guvenligi” ise, bunu “bir thread is parcacigini olunceye kadar bekleyerek” (i.e. join kullanarak) yapmak zorunda degilsin.

Bu arada join de thread olene kadar beklemek zorunda degil.

Haklisin, ayri ayri cevaplamaya calisinca sacma oluyor. Sorular beraberdi aslinda.

Neyse, iyi haberi vereyim: Basina gelen sorun butun event tabanli GUI toolkit’lerinde ortaya cikan bir sorun. Buradaki cozumu ise cok basit: GUI thread’inde join kullanmamak. Butonu disable et, yeni thread’i bloke et… bir suru yontem var. GUI thread’ini bekletme.

XY Problemine asina misin? http://xyproblem.info/ | https://fazlamesai.net/posts/xy-problemi


#7

Rica ederim. 1096 bayt yazma konusuna gelince, burada şunu kastettim. Bir birimde 1096 bayt almak var, bir de 4096 bayt almak var. Okuma-yazma usb’lerde bazen yüksek olabiliyor. Bunu da kullanmakta fayda var. Yani ben öyle düşünüyorum. Yanlış olduğunu düşünen varsa düzeltirse sevinirim.

Thread kısmına gelirsek, sizin burada birden fazla Thread kullanmanızı gerektiren bir durum yok, ki zaten kullanmamışsınız. Yukarıdaki mesajları da okuduktan sonra, ben de @aib nin dediği gibi, bir Thread’in ikinci kez başlatılmaması için önlem alman gerektiğini düşünüyorum. Kullanıcı yazdır butonuna tıkladıktan sonra bu butonu deaktif ederek, kullanıcının ikinci kez basmasını önleyerek tehlikeyi yok etmiş olursun.

Kısaca programında Thread için endişe edilecek bir durum yok. Sadece ikinci kez başlatılmasına mani olman yeter. Bunun dışında ileri seviye Thread problemleri yok burada. Onlar olsaydı biraz tartışarak birşeyler öğrenirdik belki :slight_smile:

İyi forumlar.


#8

Her thread farklı veri kısımları ile çalışırsa endişe etmenize gerek yok. Python’daki thread’ler aslında paralel çalışmazlar, o sebeple burada thread’lerin hız avantajını kullanmak isterseniz işlemlerinizi process tabanında ayırmanızı tavsiye ederim. Sanırım multiprocessing isimli bir modül vardı bununla ilgili standart kütüphanede.

Bir de Python’a yeni gelen async/await sözdizimini kullanmanızı tavsiye ederim thread’lerin metodlarını kullanmak yerine. Böylesi daha kolay, daha güvenli. Dünya da bu yöne doğru gidiyor zaten büyük bir hızla.

Projeniz ile ilgili eleştirilerim şunlar olabilir:

  1. LICENSE.md’yi sadece LICENSE olarak yazmanız daha iyi olur. Zira orada bir Markdown sözdizimi yok, zaten genelde sadece LICENSE olarak yazılır.

Bunun dışında diyebileceğim bir şey yok. Ellerinize sağlık! :slight_smile:


#9

async/await Python’da coroutine yaratiyor. Thread bazli paralellige (veya hatta herhangi bir paralellige) alternatif olarak gosterebilecegimi sanmiyorum. (Asagida deniyorum)

Thread bazli paralelligin olmadigi dillerde ana thread’i bloke etmeden (bkz: event loop) asenkron I/O yapmak icin kullaniliyor. Populerligini de JavaScript’in boyle bir dil olmasina borclu olsa gerek.

Fakat kafama takildi simdi, acaba coroutine’leri paralellik icin kullanabilir miyiz. Wikipedia oyle diyor (https://en.wikipedia.org/wiki/Coroutine#Comparison_with_threads) ama detaylandirmamis. Benim aklima ilk gelen:

async def foo():
    a, b, c = process(1), process(2), process(3)
    ...
    a_r = await a
    ...
    b_arti_c = await b + await c
    ...

Ama bu task modeli oluyo sanirim, bir yerde baslatip bir yerde bekliyoruz. a/b/c de future veya promise gibi duruyor.

Hmm, hayir; Python’da denedim, awaite kadar calismaya baslamiyorlar.

asyncio.gather yapabiliyormus (asyncio.gather(process(1), process(2), process(3)) ama beceremedim.

Asil await a + await b kodunu paralel olarak calistirabilecek bir mekanizma dusunuyorum. Kodu okuyup, a ve b'nin await edildigini gorup, fonksiyonun basinda baska thread’lerde calistirmaya baslayan gibi, ama bu kadar primitif degil. (Hmm, belki bir functor yapisiyla—denemeden fazla zirvalamiyim ama).


#10

JavaScript’te Promise.all kullanılarak await'leri paralel çalıştırmak mümkün. Python için de bir benzeri olarak şöyle bir şey buldum: https://stackoverflow.com/a/34377364/1583714


#11

async.sleep'i time.sleep ile degistirince calismiyor. Yine coroutine yani; concurrency var, parallelism yok.

Duz yazilmis kodda paralelligi applicative functor’larla yapabildim ama butun fonksiyonlari lift etmek gerekiyo. Fonksiyonlari paralel obje alip dondurme seklinde modifiye etmek yani. Yukaridaki task/promise sentaksi daha temiz olabilir.