21 Eylül 2015 Pazartesi

nohup

Giriş
Linux ve Unix'te terminalden çalıştırılan programlar, terminal kapatılınca işletim sistemi tarafından öldürülürler. İş "&" karakteri ile arka plana atılsa bile bu durum değişmez. Kullanıcı terminali kapatsa veya logoff olsa bile bazı işlerin çalışmasını isteyebilir. Bu durumda Linux ve Unix'te nohup kullanılır.

Windows'ta nohup'a direkt karşılık gelen bir şey yok. Kullanıcı terminali kapatırsa uygulamanın çalışmaya devam etmesi start komutu ile sağlanabiliyor ancak logoff olması durumunda uygulamanın çalışmaya devam edebilmesinin tek yolu uygulamayı Scheduled Task veya Servis olarak çalıştırmak.

nohup ve diğer seçenekler
Yazıya başlamadan önce şunu belirtmekte fayda var, nohup tek seçenek değil. Aynı işlevi yerine getirebilen screen, tmux, byobu gibi başka uygulamalar da var.

Zaten Çalışmakta Olan Uygulamalar İçin
disown yapılabilir. Önce Ctrl+Z ile uygulama duraklatılır. bg ile arka plana gönderilir. disown ile mevcut kabuk ile bağlantısı koparılır. Sonra kabuktan çıkılır.

nohup nedir
Açıklaması şöyle
NAME
       nohup - run a command immune to hangups, with output to a non-tty

SYNOPSIS
       nohup COMMAND [ARG]...
       nohup OPTION
Linux ve Unix'te nohup nasıl kullanılır?
nohup komutunu şöyle kullanılır.
nohup COMMAND [ARGS] &
nohup arkaplanda çalıştırılır. Böylece shell'de çalışmaya devam edebiliriz. Nohup uygulamamızın çıktısını nohup.out dosyasına yönlendirir. Bazen bu dosya çok büyük boyutlara ulaşabildiği için dikkatli olmak gerekir.

stdout akımını yönlendirmek
Eğer istersek çıktıyı dev/null'a yönlendirebiliriz.
nohup COMMAND > /dev/null &
stdout, stderror ve stdin akımlarını yönlendirmek
Eğer nohup ile çalıştırılan komut stdin, stdout, stderr gibi akımlara ihtiyaç duyuyorsa, shell'den çıkınca bu akımlar da kapatılacağı için uygulamamız donabilir. Bu durumda nohup şöyle kullanılır.
nohup myprogram > foo.out 2> foo.err < /dev/null &

stdout ve sterr akımlarını yönlendirmeyi anlamak kolay. Peki niçin stdin'i de dev/null'a yönlendiriyoruz. Uygulamamız terminalden bir şey okuyorsa artık terminali olmayacağı için donar. < dev/null ile uygulama terminalden okumaya çalışır ve EOF okur.

nohup altta ne yapar?
Normalde parent uygulama kapatılırsa veya ölürse, başlattığı child uygulamalar etkilenmezler! Ancak bir terminal kapatılırsa, terminali kontrol eden uygulama yani shell SIGHUP sinyali alır. Shell kendi session'ı içindeki her uygulamaya da SIGHUP (Hang up) sinyali gönderir. Böylece uygulamalar da ölürler.

nohup HUP sinyalini dikkate almaz. Böylece kendi başlattığı komut ta HUP sinyalinden etkilenmez.

nohup ve execvp ilişkisi
Aslında kod çok basit.
Önce nohup sinyali kaale almamasını sağlayan sistem çağrısını yapar.
signal(SIGHUP, SIG_IGN);
Daha sonra execvp çağrısı ile verilen komutu çalıştırır.
execvp(*argv, argc);

Windows'ta Start
Başka bir programı çalıştırmaya yarar.
start java -jar spider.jar
Eğer istenirse yeni pencere küçültülmüş olarak başlatılabilir. Örnek:
start /min java -jar spider.jar
Normalde program bitince pencere de kapanır. cmd /k ile yeni komut satırı açık kalır.
start cmd /k java -jar spider.jar



RS232

RS232'den Önce Ne Vardı
Açıklaması şöyle. RS232 voltaja göre çalışırken, daha önceki teknoloji akıma göre çalışıyordu. Yani telgraf teli gibiydi. 
Like other early DEC terminals, the VT50 series were equipped with both an RS-232 port as well as a 20mA current loop, an older serial standard used with teletype machines that was more suitable for transmission over long runs of twisted-pair wiring.

RS232
Seri port denilince en çok akla gelen standart RS232. Bu standart teorik olarak en az 3 kablodan oluşmaktadır. Tx (Transmit), Rx (Receive) ve Ground.

Eskiden 25 pin'li RS232 portları vardı. Daha sonra IBM 9 pinli RS232 portları çıkarttı.

Aşağıdaki şekilde 9 pinli kablo mevcut. Basit bir iletişim için sadece 2,3,5 numaralı pinleri karşı tarafa bağlamak yeterli.



RS232 bir bitin yani 1 ve 0'ı temsil etmek için kullanılması gereken voltaj seviyelerini tanımlar. Aslında bütün elektrik, optik ve Wifi sinyalleri analogtur. Analog sinyali dijital hale getirmek için bir encoding kullanılır. Manchester Code örnek verilebilir.

Basit bir kodek şöyle çalışır. Eğer sinyal %20'den küçükse 0, %80'den büyükse 1 kabul edilir.

Voltaj seviyeleri artı voltaj ve eksi voltaj olduğu için bi-polar olarak ta adlandırılıyor. Ground voltaj 0 olmak zorunda değildir. Örneğin bu voltajı 5 V seviyesine ayarlayarak, ve kabloya 3 V vererek, eksi voltaj yaratmak mümkün.

POSIX ile RS232 programlamak için termios yapısı yazısına bakabilirsiniz.

RS485
RS485 RS232 ile aynı fakat daha uzun mesafelerde kullanılabiliyor.

RS422
RS422 burada.

20 Eylül 2015 Pazar

Java 8 Stream Sınıfları


Functional Paketi
Java 8 Functional Kavramları yazısına taşıdım.

Arayüzler
Tüm arayüzler BaseStream<T>'den kalıtıyor.
Stream<T> gibi generic veya IntStream, LongStream gibi generic olmayan bir sürü arayüz geliyor.
Bu arayüzler arasında allMatch(), anyMatch(), collect(), concat(), count() gibi ortak metodlar var.

Stream Arayüzü
Stream arayüzünü metodlardan dönmek yerine collect metodu ile elde edilen listeyi dönmek çok daha iyi. Örnekte Stream dönen bir metod var
Stream<T> deriveSomethingMeaningfulFromPrivateState() {
    return myPrivateThingies.stream()
        .map(this::ownerOfthing)
        .map(Owner::socialStatus)
        .filter(SocialStatus::isHeAFineMatey);
        // No collect
}
Bence Stream yerine Collection dönen bir metod daha iyi anlaşılır.
ImmutableSet<T> deriveSomethingMeaningfulFromPrivateState() {
    return myPrivateThingies.stream()
        .map(this::ownerOfThing)
        .map(Owner::socialStatus)
        .filter(SocialStatus::isHeAFineMatey)
        .collect(MyCustomCollectors.toImmutableSet());
}
anyMatch
Bu metod C#'taki Enumerable.Any ile aynı işlevi yerine getiriyor.
if (Stream.of(">", "<", "&", "l", "p").anyMatch(string::contains)) {
  ...
}

collect metodu
collect() metodu içine bir collector alır. Collector stream içindeki elemanlara bir işlem uygular. Stream sınıfları ile bir çok collector geliyor.

List'e şöyle çevrilir.
theIntStream.collect(Collectors.toList())
Map'e şöyle çevrilir.
Map<String, String> map =
    orders.stream ()
          .collect (Collectors.toMap (SomeOrder::getID,SomeOrder::getSummary));

Örnek'te string'leri birleştiren Collectors.joining() görülebilir.
Arrays.stream(s.split(Pattern.quote("||")))
   .distinct()
   .filter(st -> !st.isEmpty()) 
   .collect(Collectors.joining("||"));

Örnek'te nesneleri gruplayan Collectors.groupingBy() görülebilir.
Map<String, Long> result = 
 Stream.of(text1, text2, text3 .... text10)
 .flatMap(list -> list.stream())
 .collect(Collectors.groupingBy(x -> x, Collectors.counting()));
distinct metodu
SQL'deki distinct ile aynı işlemi yapar. Birden fazla olan elemanlardan sadece bir tanesini seçer. Örnek
Arrays.stream(s.split(Pattern.quote("||")))
   .distinct();
flatMap
Java 8 Stream flatMap yazısına taşıdım.

filter metodu
Örnek:
LinkedList<User> users = new LinkedList<>();
users.add(new User(1, "User1"));
users.add(new User(2, "User2"));
users.add(new User(3, "User3"));
List<User> resultUserList = users.stream()
        .filter(user -> user.getId() == 1)
        .collect(Collectors.toList());
findFirst
Akımdaki ilk elemanı verir. Genellikle get() ile beraber kullanılır.
System.out.println(
            "Result: " +
            Stream.of(1, 2, 3)
                    .filter(i -> {
                        System.out.println(i);
                        return true;
                    })
                    .findFirst()
                    .get()
    );

foreach
Her bir eleman için bir metodu çağırır.

mapToInt Metodu
Linq'teki select gibi nesnenin dönüşmesini sağlar. Aslında IntStream nesnesi döner. Bu nesne ile normal Stream<T> sınıfında olmayan average(), sum() gibi metodları kullanabiliriz.
double average = roster
.stream()
.filter(new Predicate<Person>(){
          public boolean test(Person p){
              return p.getGender() == Person.Sex.MALE;
           }
      })
.mapToInt(Person::getAge)
.average()
.getAsDouble();

max metodu
Listedeki en büyük elemanı bulur. Örnek:
System.out.println(list.stream().max(Integer::compare).get());
System.out.println(list.stream().min(Integer::compare).get());
of metodu
Verilen diziyi stream'e çevirir. Örnek:
public static void main(final String[] args) throws Exception {   
    Stream.of(args).forEach(System.out::println);
}
Bir başka örnek
System.out.println(Stream
        .of("a", "b", "c", "d", "e", "f")
        .reduce("", (s1, s2) -> s1 + "/" + s2)
    );
peek
Sadece debug amaçlı kullanılması gerekiyormuş.

reduce
reduce identity, accumulator ve combiner isimli üç metod alır. Örnek
BinaryOperator<String> accumulator = (s1, s2) -> {
    System.out.println("joining \"" + s1 + "\" and \"" + s2 + "\"");
    return s1 + "/" + s2;
};
System.out.println(Stream
                .of("a", "b", "c", "d", "e", "f")
                .parallel()
                .reduce("", accumulator)
);
toArray
Sonucu array olarak alabilmemizi sağlar. Örnekte bir input dizisi P tipinden bir başka diziye çevriliyor.
Arrays.stream(inputArray).map(e -> e.transformToP()).toArray(P[]::new);

IntStream arayüzü
IntStream yazısına taşıdım.