İşlerin Durdurulması ve Sonlandırılması
Önceki Bir İş Denetim kabuğunun Gerçeklenmesi Sonraki
İşlerin Durdurulması ve Sonlandırılması
Bir önalan işi başlatıldığında, kabuk, işteki tüm süreçler durana ya da sonlanana kadar beklemelidir. Bunu waitpid çağrısı ile yapabilir; bkz. Süreç Tamamlama. Süreçlerin durması ya da sonlanması halinde durumu raporlamaları için WUNTRACED seçeneği kullanılır.
Kabuk bir artalan işinin kullanıcı tarafından durdurulması ya da sonlandırılmasının da raporlanmasını ayrıca beklemelidir; bu waitpid işlevinin WNOHANG seçeneği ile çağrılması ile yapılabilir. Bu sınamanın yapılacağı en iyi yer yeni bir komut isteminin hemen öncesidir.
Kabuk ayrıca, SIGCHLD sinyallerine bir sinyal eylemci kurmuş bir alt süreç için durum bilgisi içeren bir eşzamansız uyarı alabilir.
Örnek kabuk yazılımında, SIGCHLD sinyalleri normal olarak yoksayılmaktadır. Bu, kabuğun zaman zaman değiştirdiği genel veri yapılarından kaynaklanan evresellik (reentrancy) sorunlarında kaçınmak içindir. Fakat belirli zamanlarda, kabuğun bu veri yapılarını kullanmadığı zamanlarda ( örneğin, uçbirimden girdi beklerken), SIGCHLD sinyali için bir eylemciyi etkinleştirmeye ihtiyaç duyar. Eşzamanlı durum sınamaları yapmak için kullanılan işlev (bu durumda do_job_notification işlevi), bu eylemci tarafından ayrıca çağrılabilir.
Burada, örnek kabuk yazılımından işlerin durumunu sınayıp durumu kullanıcıya bildiren parçası görülmektedir:
/* waitpid tarafından döndürülen  süreç kimliğinin durumunu
   saklayalım. İstenen yapıldıysa 0 yoksa sıfırdan farklı
   bir değerle dönelim..  */

int
mark_process_status (pid_t pid, int status)
{
  job *j;
  process *p;

  if (pid > 0)
    {
      /* Süreç için kaydı güncelleyelim.  */
      for (j = first_job; j; j = j->next)
        for (p = j->first_process; p; p = p->next)
          if (p->pid == pid)
            {
              p->status = status;
              if (WIFSTOPPED (status))
                p->stopped = 1;
              else
                {
                  p->completed = 1;
                  if (WIFSIGNALED (status))
                    fprintf (stderr, "%d: %d sinyali ile sonlandırıldı.\n",
                              (int) pid, WTERMSIG (p->status));
                }
              return 0;
              }
      fprintf (stderr, "%d kimlikli bir süreç yok.\n", pid);
      return -1;
    }
  else if (pid == 0 || errno == ECHILD)
    /* Rapor verecek süreç yok.  */
    return -1;
  else {
    /* Diğer tuhaf hatalar.  */
    perror ("waitpid");
    return -1;
  }
}

/* Süreçleri beklemeden durum bilgilerinin varlığını sınayalım.  */

void
update_status (void)
{
  int status;
  pid_t pid;

  do
    pid = waitpid (WAIT_ANY, &status, WUNTRACED|WNOHANG);
  while (!mark_process_status (pid, status));
}

/* Belirtilen işteki tüm süreçleri beklerken
   durum bilgilerinin varlığını sınayalım.  */

void
wait_for_job (job *j)
{
  int status;
  pid_t pid;

  do
    pid = waitpid (WAIT_ANY, &status, WUNTRACED);
  while (!mark_process_status (pid, status)
          && !job_is_stopped (j)
          && !job_is_completed (j));
}

/* İş durumu ile ilgili bilgileri kullanıcıya sunmak için biçimleyelim.  */

void
format_job_info (job *j, const char *status)
{
  fprintf (stderr, "%ld (%s): %s\n", (long)j->pgid, status, j->command);
}

/* Durmuş ya da sonlandılılmış işler hakkında kullanıcıyı uyaralım.
   Sonlanmış işleri etkin iş listesinden kaldıralım.  */

void
do_job_notification (void)
{
  job *j, *jlast, *jnext;
  process *p;

  /* Alt sürecin durum bilgisini güncelleyelim.  */
  update_status ();

  jlast = NULL;
  for (j = first_job; j; j = jnext)
    {
      jnext = j->next;

      /* Tüm süreçler tamamlanmışsa, kullanıcıya işin tamamlandığını
         bildirelim ve onu etkin işler listesinden silelim.  */
      if (job_is_completed (j)) {
        format_job_info (j, "iş tamamdır");
        if (jlast)
          jlast->next = jnext;
        else
          first_job = jnext;
        free_job (j);
      }

      /* Duran işleri kullanıcıya bildirelim ve
         bunu bir daha yapmamak için onları imleyelim.  */
      else if (job_is_stopped (j) && !j->notified) {
        format_job_info (j, "iş durdu");
        j->notified = 1;
        jlast = j;
      }

      /* Hala sürmekte olan işler için bir şey söylemek gerekmez.  */
      else
        jlast = j;
    }
}
Önceki Üst Ana Başlık Sonraki
Önalan ve Artalan Başlangıç Duran İşlerin Sürdürülmesi
Bir Linux Kitaplığı Sayfası