2016-12-09 6 views
1

昨日私はSynthasizerをギフトとして持っていて、それにデータを書きたいと思っていました。これはうまく機能しています。 それから、Ctrl + Cを押さえて閉じることがうまくいくと思いました。 ファイル記述子を閉じるだけで問題になるのは、MIDIデバイスが最後に与えられたノートを処理していることです。そのため、MIDIデバイスにミュートを指示するミュート機能を書いています。それは動作します。信号機能を持つ他の関数を呼び出すにはどうすればよいですか?

それで、シグナルハンドラが終了する前にデバイスをミュートしようとしましたが、それ以来苦労しています。シグナル(SIGINT、intHandler);関数は追加引数を取らない。だから私は賢明だと思って、信号関数を呼び出して、デバイスファイル記述子とデータポインタを取り、最後に最後の書き込みを行うことができるようになる関数mySigを書き出して終了します。

IDKでも動作するかもしれませんが、mySig関数は最初から呼び出されているようですが、スケーリングは決して起こりません。

信号機能を使用してプログラムを終了する前に、ミュート機能を呼び出すにはどうすればよいですか?

この私の最初の信号の受け渡しプログラム、イム実行するLinuxは、あるプログラムがC.

#include <sys/soundcard.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 
static volatile int keepRunning = 1; 
char* device = "/dev/midi1"; 
//function headers: 
void mute(int fd, char *data); 
void intHandler(int dummy); 
void mySig(void (*intHandler)(int dummy), int fd, char *data); 

int main(void){ 

    unsigned int note=50; 

    char data[3] = {0x90, note, 33}; //device address, note, volume 
    int fd = open(device, O_WRONLY, 0); 
    if(fd < 0){ 
     printf("Error: cannot open Synth %s\n", device); 
     exit(1); 
     } 
    signal(SIGINT, intHandler);  
//  mySig(intHandler,fd,data); 

while(keepRunning){ 
    for(note=30; note < 95; note++){ 
     data[1]=note;//change note 
     write(fd, data, sizeof(data)); 
     usleep(100000); 
     if(note>=89){ 
      note =30; 
      } 
     } 
mute(fd,data); //mutes the data stream. 
    close(fd); // close device 

    return 0; 
} 
} 
//functions: 
void mute(int fd, char *data){ 
    data[2]=0;//setVolume to 0 
    write(fd, data, sizeof(data)); 
    close(fd); 
    } 

void mySig(void (*intHandler)(int dummy), int fd, char *data){ 
    printf("my Sig has been called\n"); 
    mute(fd,data); 
    signal(SIGINT, intHandler); 
    } 

void intHandler(int dummy) { 
    printf("my Sig has been called\n"); 
    keepRunning = 1; 
    printf("ctrl+c was pressed, exiting\n"); 
    usleep(10000); 
    exit(1); 
} 
+0

は、より良いタイトルplsを提案します。 – j0h

+0

タイトルはこの質問の唯一の明確な部分です。 –

+0

http://stackoverflow.com/questions/6970224/providing-passing-argument-to-signal-handler – dekkard

答えて

0

使用でのみごkeepRunningフラグをクリアするシグナルハンドラです。 は個人的に、私はdoneのように、反対のフラグを好む:

static volatile sig_atomic_t done = 0; 

static void done_handler(int signum) 
{ 
    done = 1; /* Or, in Linux, done = signum. */ 
} 

static int install_done(const int signum) 
{ 
    struct sigaction act; 

    memset(&act, 0, sizeof act); 

    sigemptyset(&act.sa_mask); 
    act.sa_flags = 0; 
    act.sa_handler = done_handler; 
    if (sigaction(signum, &act, NULL) == -1) 
     return errno; 

    return 0; 
} 

ユーザが端末のプログラムを実行し、それらが予想外に、端末を閉じると、プログラムはSIGHUP信号を受信します。 Ctrl + Cは、SIGINTシグナルを引き起こします。 SIGTERMは、プログラムに終了を要求するためによく使用されます。だから私は個人的にやりたいです。

if (install_done(SIGINT) || 
     install_done(SIGHUP) || 
     install_done(SIGTERM)) { 
     fprintf(stderr, "Cannot install signal handlers: %s.\n", strerror(errno)); 
     return EXIT_FAILURE; 
    } 

私のmain()の早い段階です。

あなたがする必要があるすべては、あなたのループを持つことである -

while (!done) { 
     /* Play notes or whatever */ 
    } 

とループの後、私の場合には、最後の音をミュートするデバイスを閉じ、果たしました。

要求の信号をただちに終了するようにしてください。すぐに終了するという要求ではありません。プログラムは、終了を要求する信号を受け取ったときに必要なクリーンアップを行うことが期待されています。プログラムがの場合はのように終了したい場合は、いつでもSIGKILLでプロセスを終了させることができます。

関連する問題