zoukankan      html  css  js  c++  java
  • Linux信号机制代码示例

    1 基本功能
    本Blog创建了两个进程(父子进程):

    • 父进程
      执行文本复制操作,当收到 SIGUSR1信号后,打印出现在文件复制的进度;
    • 子进程
      每个固定时间段向父进程发送一个 SIGUSR1 信号。

    2 代码示例

    /*
     * File: Signal.c
     *Description: Two process
        1. Father:  copy a file, when receive the SIGUSR1 signal, print the progress
        2. Child: timing trigger the parent process
     *Autor: Jimmy Nie
     */
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/fcntl.h>
    
    void handler(int sig);
    void SigAlarm(int sig);
    
    int count = 0;      //has read bytes
    int fileSize = 0;   //the source file size
    
    int main(int argc, char *argv[])
    {
        //variable define
        int fd_src, fd_dst;
        int tmp = 0;        //how many bytes read every time
        char buf[128] ;      //tempature storage buffer
    
        //0. check the argument
        if(argc != 3)
        {
            printf("%s(%d): Check the arguments, argument=%d(3 is need)
    ", argc);
            exit(EXIT_FAILURE);
        }
    
        //1. open the file
        if(-1 == (fd_src=open(argv[1], O_RDONLY)))
        {
            perror("open");
            exit(EXIT_FAILURE);
        }
    
        //open the destination file, if it does not exist, creat it first
        if(-1 == (fd_dst=open(argv[2], O_RDWR|O_CREAT, 0644)))
        {
            perror("open");
            exit(EXIT_FAILURE);
        }
    
        //2. Obtain the source file size
        fileSize = lseek(fd_src, 0, SEEK_END);
        if(fileSize < 0)
        {
            perror("lseek");
            exit(EXIT_FAILURE);
        }
        
         lseek(fd_src, 0, SEEK_SET);
    
        //3. Father process install SIGUSR1 signal
        if(signal(SIGUSR1, handler) == SIG_ERR)
        {
            perror("signal");
            exit(EXIT_FAILURE);
        }
    
        //4. Creat a new process(child)
        pid_t  pid;
        if(-1 == (pid=fork()))
        {
            perror("fork");
            exit(EXIT_FAILURE);
        }
    
        //In child process
        else if(pid == 0)
        {
            //Install the signal SIGALRM
            if(signal(SIGALRM, SigAlarm) == SIG_ERR)
            {
                perror("signal");
                exit(EXIT_FAILURE);
            }
    
            ualarm(200,10000);  //after 20ms start trigger, and every 50ms trigger once
            //alarm(1);
    
            while(1)    //execute continues
                ;
        }
    
        //In parent process
        else
        {
            //3. copy source file to destination file
            while(1)
            {
                //read the source file to buf
                if(-1 == (tmp=(read(fd_src, buf, 128))))
                {
                    perror("read");
                    exit(EXIT_FAILURE);
                }
    
                //check the end of file
                if(0 == tmp)
                {
                    printf("Finished copy the file, and file size:%d
    ", fileSize);
                    kill(pid, SIGINT);      //finished copy, trigger a signal to child, and terminate child process
                    break;
                }
    
                //write the buffer to the destination file
                if(-1 == write(fd_dst, buf, tmp))
                {
                    perror("Write");
                    exit(EXIT_FAILURE);
                }
    
                count += tmp;
            }
    
            wait(NULL);     //wait child process exit
            close(fd_src);
            close(fd_dst);
        }
    
    
        return 0;
    }
    
    //function used to print the progree of copy file
    void handler(int sig)
    {
        int i = 0;
        i = (int)(((float)count / (float)fileSize) * 100);
        printf("
    Has copyed %d%% 
    ",i);
    
        int j = 0;
        for(j=0; j<i; j++)
        {
            if(j%2)
                printf("*");
        }
    
        printf("
    ");
    }
    
    //used to send SIGUSR1 signal to parent process
    void SigAlarm(int sig)
    {
        kill(getppid(), SIGUSR1);
        //alarm(1);
    }
    
    

    编译该代码:

    
    [root@niesh Linux]# gcc -o signal signal.c
    [root@niesh Linux]# ll
    总用量 36
    -rwxrwxr-x. 1 niesh niesh  8659 9月  22 22:07 produce
    -rw-rw-r--. 1 root  niesh   467 9月  22 22:07 produce.c
    -rwxr-xr-x. 1 root  root  13445 9月  23 11:26 signal
    -rw-rw-r--. 1 root  niesh  3407 9月  22 22:45 signal.c
    

    但是此时我们还需要一个大于1M的ASCII文件,使得CP不至于瞬间完成:

    #include <stdio.h>
    #include <sys/fcntl.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
        int fd;
        int count = 0;
        char buf[] = "Hello,world
    ";
    
        fd = open(argv[1], O_RDWR|O_CREAT, 0644);
        
        for(count=0; count < 1024*1024; count++)
            write(fd, buf, strlen(buf));        //file size = 16*256*1024*1024 = 4Mbyte
    
        //printf("The sizeof(buf)=%d
    ",sizeof(buf));
        close(fd);
    
        return 0;
    }
    
    

    通过以上代码我们可以产生出一个12M的文本文件:

    
    [root@niesh Linux]# gcc -o produce produce.c
    [root@niesh Linux]# ./produce test
    [root@niesh Linux]# ll -h
    总用量 13M
    -rwxr-xr-x. 1 root root  8.5K 9月  23 11:31 produce
    -rw-rw-r--. 1 root niesh  467 9月  22 22:07 produce.c
    -rwxr-xr-x. 1 root root   14K 9月  23 11:26 signal
    -rw-rw-r--. 1 root niesh 3.4K 9月  22 22:45 signal.c
    -rw-r--r--. 1 root root   12M 9月  23 11:31 test            //ASCII文件 12M
    
    

    3 执行效果

    
    [root@niesh Linux]# ./signal test t1
    
    Has copyed 1%
    
    
    Has copyed 3%
    *
    
    Has copyed 6%
    ***
    
    Has copyed 7%
    ***
    
    Has copyed 9%
    ****
    
    Has copyed 10%
    *****
    
    Has copyed 15%
    *******
    
    Has copyed 21%
    **********
    
    Has copyed 25%
    ************
    
    Has copyed 29%
    **************
    
    Has copyed 34%
    *****************
    
    Has copyed 42%
    *********************
    
    Has copyed 44%
    **********************
    
    Has copyed 48%
    ************************
    
    Has copyed 54%
    ***************************
    
    Has copyed 58%
    *****************************
    
    Has copyed 65%
    ********************************
    
    Has copyed 71%
    ***********************************
    
    Has copyed 76%
    **************************************
    
    Has copyed 80%
    ****************************************
    
    Has copyed 88%
    ********************************************
    
    Has copyed 93%
    **********************************************
    
    Has copyed 97%
    ************************************************
    Finished copy the file, and file size:12582912
    
    

    查看复制后的结果:

    
    [root@niesh Linux]# ll -h
    总用量 25M
    -rwxr-xr-x. 1 root root  8.5K 9月  23 11:31 produce
    -rw-rw-r--. 1 root niesh  467 9月  22 22:07 produce.c
    -rwxr-xr-x. 1 root root   14K 9月  23 11:26 signal
    -rw-rw-r--. 1 root niesh 3.4K 9月  22 22:45 signal.c
    -rw-r--r--. 1 root root   12M 9月  23 11:42 t1                //复制后生成的文件
    -rw-r--r--. 1 root root   12M 9月  23 11:31 test
    
    
  • 相关阅读:
    pionter指针小结
    C++笔记 5
    C++笔记 3
    ipad safari 滚动(overflow)解决方案
    IE9 BUG overflow :auto 底部空白解决方案
    asp.net 导出EXCEL超高兼容(不用装Excel)
    jquery post 同步异步总结
    jquery-alert对话框
    左固定右边自适应框架
    删除Cookies
  • 原文地址:https://www.cnblogs.com/Jimmy1988/p/7580701.html
Copyright © 2011-2022 走看看