Soru C'deki başka bir süreci nasıl doğuruyorsunuz?


Harici bir programı nasıl çalıştırıyorsunuz ve C kullanarak komut satırı parametrelerini aktarıyorsunuz? İşletim sistemi API'sini kullanmanız gerekiyorsa, Windows, Mac ve Linux için bir çözüm ekleyin.


25
2017-08-19 22:53


Menşei


Sanırım sorunuzu yeniden yazmanız gerekiyor - harici bir işlem açmak değil kesinlikle başka bir süreç ortaya çıkmasıyla aynı ... bir fark var. - Jason Bunting


Cevaplar:


Gerçekten, tam olarak ne yapmaya çalıştığınıza bağlı olarak değişir:

  1. İşletim sistemi bağımlı
  2. Ne yapmaya çalıştığını tam olarak açık değil.

Yine de, karar vermeniz için bazı bilgileri sağlamaya çalışacağım.
UNIX'te fork() Çatal aradığınız yerden işleminizin bir klonunu oluşturur. Anlamı, eğer aşağıdaki süreç varsa:

#include <unistd.h>
#include <stdio.h>

int main()
{
    printf( "hi 2 u\n" );
    int mypid = fork();

    if( 0 == mypid )
        printf( "lol child\n" );
    else
        printf( "lol parent\n" );

    return( 0 );
}

Çıkış aşağıdaki gibi görünecektir:

merhaba 2
    lol çocuk
    ana baba

Sen ne zaman fork() Çocuğa iade edilen pid 0'dır ve ebeveynin içinde döndüğü pid, çocuğun pididir. "Hi2u" nun yalnızca bir kez basıldığı dikkat edin ... ebeveyn.

execve() ve işlev ailesi neredeyse her zaman fork().  execve() ve benzerleri geçerli stackframe'in üzerine yazdığınız uygulamanın adıyla yazılır. execve() neredeyse her zaman kullanılır fork() Bir çocuk sürecini çatalladığınız yer ve eğer ebeveynseniz, yapmaya devam etmeniz gereken her şeyi yapıyorsunuz ve eğer çocuksanız yeni bir süreç yürütüyorsunuz. execve() ayrıca hemen hemen her zaman kullanılır waitpid() - waitpid bir çocuk sürecinin bir pidini alır ve tam anlamıyla, bekler Çocuğun sonlanmasına ve çocuğun çıkış durumunu size iade edene kadar.

Bu bilgiyi kullanarak çok basit bir kabuk yazabilmelisiniz; İşlem isimlerini komut satırında alan ve anlattığınız işlemleri çalıştıran bir. Tabii ki, kabuklar boru girişleri ve çıkışları gibi, bundan daha fazlasını yapar, ancak temelleri kullanarak temellerini gerçekleştirebilmeniz gerekir. fork(), execve() ve waitpid().

Not: Bu * nix özgüdür! Bu, Windows üzerinde çalışmayacak. 

Umarım bu yardımcı oldu.


15
2017-08-21 18:44





Harici programın çıktısını okumak gibi daha karmaşık işlemler yapmak istiyorsanız, daha iyi popen sistem çağrısı. Örneğin, bir dizin girişine programlı olarak erişmek için (bu biraz saçma bir örnektir, ancak yararlıdır) gibi bir örnek) şöyle bir şey yazabilirsiniz:

#include <stdio.h>

int main()
{
  int entry = 1;
  char line[200];
  FILE* output = popen("/usr/bin/ls -1 /usr/man", "r");
  while ( fgets(line, 199, output) )
  {
    printf("%5d: %s", entry++, line);
  }
}

böyle bir çıktı vermek

1: cat1
2: cat1b
3: cat1c
4: cat1f
5: cat1m
6: cat1s
...

14
2017-08-20 01:52





#include <stdlib.h>

int main()
{
    system("echo HAI");

    return 0;
}

11
2017-08-19 22:58



Asla sistemi kullanmayın. Çok iş parçacığı güvenliğinden uzak, sizi zor ve gereksiz yere ısırır. Sinyal işleme hataları örneğin en kötü problemlerden bazıları ve "sistem" bununla dolu. - Lothar


Sistemi kullanmamak için büyük bir uyarı vermek istiyorum ve bir kütüphane yazarken% 100'ü asla kullanmayın. Multixreading'in Unix adı verilen oyuncak işletim sistemine bilinmediği 30 yıl önce tasarlandı. Ve hemen hemen tüm programlar bugün çok iş parçacıklı olsa bile kullanılamaz.

Popen kullanın ya da fork + execvp yapın, diğer her şey, sinyal işleme, çevre işleme kodundaki çarpışmalar vb. İle ilgili problemleri bulmakta zorlanır. Saf kötülük ve seçilen ve en çok oylanan yanıtın "sistem kullanımını" desteklemesi ayıptır. ". İşyerinde Kokain kullanımını teşvik etmek daha sağlıklıdır.


5
2017-12-28 18:33





UNIX'te, yumurtlama sürecinin spagözünüzden ayrılmaya çalışmasını istiyorsanız temelde çatallamanız gerektiğini düşünüyorum: Örneğin, yumurtlama sürecinizi bıraktığınızda ortaya çıkan sürecin sonlanmasını istemiyorsanız.

Burada bir Fork, System, Exec arasındaki tüm ince farkları açıklayan sayfa.

Eğer Win, Mac ve Linux üzerinde çalışıyorsanız, size Qt Framework ve QProcess nesnesiama senin için bir seçenek olup olmadığını bilmiyorum. Büyük avantajlar, windows linux ve mac üzerinde aynı kodu derleyebilmeniz:

 QString program = "./yourspawnedprogram";
 QProcess * spawnedProcess = new QProcess(parent);
 spawnedProcess->start(program);
 // or spawnedProcess->startDetached(program);

Ve ek olarak, çocuk sürecini anne sürecinden bile öldürebilirsiniz, ve bir dere ile iletişim kurmaya devam edin.


4
2017-08-19 23:47





Bir çözüm, stdlib.h dosyasında tanımlanan sistem işlevidir.

int system(const char *string);

sistem api örneği


2
2017-08-19 22:59





Harici komutunuzun çıktısını kontrol etmek / okumak / ayrıştırmak gerekirse, sistem () yerine popen () kullanmayı öneririm.


1
2017-12-23 16:08





Windows kullanımına göre platform bağımlı tariflerden bahsetme Süreci oluşturmak, Posix'de (Linux, Mac) kullanımı fork + execvp. Fakat system() Temel ihtiyaçlarınızı karşılamalı ve standart kütüphanenin bir parçası olmalıdır.


1
2017-12-23 16:30