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)\n", 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\n", 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("\nHas copyed %d%% \n",i);
int j = 0;
for(j=0; j<i; j++)
{
if(j%2)
printf("*");
}
printf("\n");
}
//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\n";
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\n",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