linux 进程通讯之信号
来源:互联网 发布:mac d for danger 编辑:程序博客网 时间:2024/05/01 11:48
1 查看系统所有信号的命令
kill -l
2 查看某一个信号的值
kill -l 信号名称
例如: kill - l HUP
3 定义信号处理函数
可以通过signal函数来注册处理函数。
函数原型:sighandler_t signal(int signum , sighandler_t handler);
参数:signum 为要处理的信号的值
handler 该参数可以取三种值 1 SIG_IGN 表示忽略该信号
2 SIG_DFL 表示恢复对信号的系统默认处理
sighandler_t 信号处理函数的指针,指向我们自己定义的处理函数。
返回值:信号处理函数指针,如果有错误则返回SIG_ERR(-1)。
sighandler_t定义如下
typedef void (*sighandler_t)(int);
是一个指向void fun(int para)类型的指针。
4 发送信号
int kill(pid_t pid, int sig);
参数 pid 要发送到的程序的pid,
sig 要发送的信号值
返回值:0成功,非0失败 ,常见的错误如下:
给定的信号无效(errno = EINVAL)
发送权限不够( errno = EPERM )
目标进程不存在( errno = ESRCH )
6 示例代码:
void onsignal(int sig)
{
switch(sig)
{
case 63:
printf("I get signal 63\n");
break;
case 64:
printf("I get signal 64\n");
break;
}
}
int main(int argc, char *argv[])
{
return 0;
signal(63, onsignal);
signal(64, onsignal);
while(1)
{
sleep(100);
}
return 0;
}
运行上面的程序,在命令行输入kill -63 pid 或者kill -64 pid
就可以看到下面的信息
I get signal 63 或者I get signal 64
7 通过程序名获取pid.
上面的例子是通过命令行发信号,如果要在程序中发信号,需要通过程序名称获取pid,下面是示例代码
int getpid_by_name( char* ProcName, int* foundpid ,int len)
{
DIR *dir;
struct dirent *d;
int pid, i;
char *s;
int pnlen;
i = 0;
foundpid[0] = 0;
pnlen = strlen(ProcName);
/* Open the /proc directory. */
dir = opendir("/proc");
if (!dir)
{
printf("cannot open /proc");
return -1;
}
/* Walk through the directory. */
while ((d = readdir(dir)) != NULL)
{
char exe [PATH_MAX+1];
char path[PATH_MAX+1];
int len;
int namelen;
/* See if this is a process */
if ((pid = atoi(d->d_name)) == 0)continue;
snprintf(exe, sizeof(exe), "/proc/%s/exe", d->d_name);
if ((len = readlink(exe, path, PATH_MAX)) < 0)
continue;
path[len] = '\0';
/* Find ProcName */
s = strrchr(path, '/');
if(s == NULL) continue;
s++;
/* we don't need small name len */
namelen = strlen(s);
if(namelen != pnlen) continue;
if(!strncmp(ProcName, s, pnlen))
{
/* to avoid subname like search proc tao but proc taolinke matched */
if( len>i)
{
foundpid[i] = pid;
i++;
}
}
}
closedir(dir);
return i;
}
8 示例代码
void onsignal(int sig)
{
switch(sig)
{
case 63:
printf("I get signal 63\n");
break;
case 64:
printf("I get signal 64\n");
break;
}
}
int main(int argc, char *argv[])
{
if( argc>1)
{
signal(63, onsignal);
signal(64, onsignal);
while(1)
{
sleep(100);
}
}
else
{
int pid[5];
int mypid;
int otherpid;
int ret;
int find =0;
while(1)
{
ret = getpid_by_name("my-test",pid,5);
if(ret>=2)
{
int i;
mypid=getpid();
for(i=0;i<ret;i++)
{
if(mypid==pid[i])
{
continue;
}
else
{
otherpid=pid[i];
find =1;
break;
}
}
if(find )
{
break;
}
}
else
{
sleep(5);
}
}
while(1)
{
printf("send 63 to pid(%d)\n",otherpid);
kill(otherpid, 63);
sleep(5);
printf("send 64 to pid(%d)\n",otherpid);
kill(otherpid, 64);
sleep(5);
}
}
return 0;
}
假设我们的程序名称为my-test
只要分别运行 my-test 1 &
和my-yest &
就可以看到交替打印
send 63 to pid(289)
I get signal 63
send 64 to pid(289)
I get signal 64
send 63 to pid(289)
I get signal 63
send 64 to pid(289)
I get signal 64
send 63 to pid(289)
I get signal 63
send 64 to pid(289)
I get signal 64
。。。。。
kill -l
2 查看某一个信号的值
kill -l 信号名称
例如: kill - l HUP
3 定义信号处理函数
可以通过signal函数来注册处理函数。
函数原型:sighandler_t signal(int signum , sighandler_t handler);
参数:signum 为要处理的信号的值
handler 该参数可以取三种值 1 SIG_IGN 表示忽略该信号
2 SIG_DFL 表示恢复对信号的系统默认处理
sighandler_t 信号处理函数的指针,指向我们自己定义的处理函数。
返回值:信号处理函数指针,如果有错误则返回SIG_ERR(-1)。
sighandler_t定义如下
typedef void (*sighandler_t)(int);
是一个指向void fun(int para)类型的指针。
4 发送信号
int kill(pid_t pid, int sig);
参数 pid 要发送到的程序的pid,
sig 要发送的信号值
返回值:0成功,非0失败 ,常见的错误如下:
给定的信号无效(errno = EINVAL)
发送权限不够( errno = EPERM )
目标进程不存在( errno = ESRCH )
6 示例代码:
void onsignal(int sig)
{
switch(sig)
{
case 63:
printf("I get signal 63\n");
break;
case 64:
printf("I get signal 64\n");
break;
}
}
int main(int argc, char *argv[])
{
return 0;
signal(63, onsignal);
signal(64, onsignal);
while(1)
{
sleep(100);
}
return 0;
}
运行上面的程序,在命令行输入kill -63 pid 或者kill -64 pid
就可以看到下面的信息
I get signal 63 或者I get signal 64
7 通过程序名获取pid.
上面的例子是通过命令行发信号,如果要在程序中发信号,需要通过程序名称获取pid,下面是示例代码
int getpid_by_name( char* ProcName, int* foundpid ,int len)
{
DIR *dir;
struct dirent *d;
int pid, i;
char *s;
int pnlen;
i = 0;
foundpid[0] = 0;
pnlen = strlen(ProcName);
/* Open the /proc directory. */
dir = opendir("/proc");
if (!dir)
{
printf("cannot open /proc");
return -1;
}
/* Walk through the directory. */
while ((d = readdir(dir)) != NULL)
{
char exe [PATH_MAX+1];
char path[PATH_MAX+1];
int len;
int namelen;
/* See if this is a process */
if ((pid = atoi(d->d_name)) == 0)continue;
snprintf(exe, sizeof(exe), "/proc/%s/exe", d->d_name);
if ((len = readlink(exe, path, PATH_MAX)) < 0)
continue;
path[len] = '\0';
/* Find ProcName */
s = strrchr(path, '/');
if(s == NULL) continue;
s++;
/* we don't need small name len */
namelen = strlen(s);
if(namelen != pnlen) continue;
if(!strncmp(ProcName, s, pnlen))
{
/* to avoid subname like search proc tao but proc taolinke matched */
if( len>i)
{
foundpid[i] = pid;
i++;
}
}
}
closedir(dir);
return i;
}
8 示例代码
void onsignal(int sig)
{
switch(sig)
{
case 63:
printf("I get signal 63\n");
break;
case 64:
printf("I get signal 64\n");
break;
}
}
int main(int argc, char *argv[])
{
if( argc>1)
{
signal(63, onsignal);
signal(64, onsignal);
while(1)
{
sleep(100);
}
}
else
{
int pid[5];
int mypid;
int otherpid;
int ret;
int find =0;
while(1)
{
ret = getpid_by_name("my-test",pid,5);
if(ret>=2)
{
int i;
mypid=getpid();
for(i=0;i<ret;i++)
{
if(mypid==pid[i])
{
continue;
}
else
{
otherpid=pid[i];
find =1;
break;
}
}
if(find )
{
break;
}
}
else
{
sleep(5);
}
}
while(1)
{
printf("send 63 to pid(%d)\n",otherpid);
kill(otherpid, 63);
sleep(5);
printf("send 64 to pid(%d)\n",otherpid);
kill(otherpid, 64);
sleep(5);
}
}
return 0;
}
假设我们的程序名称为my-test
只要分别运行 my-test 1 &
和my-yest &
就可以看到交替打印
send 63 to pid(289)
I get signal 63
send 64 to pid(289)
I get signal 64
send 63 to pid(289)
I get signal 63
send 64 to pid(289)
I get signal 64
send 63 to pid(289)
I get signal 63
send 64 to pid(289)
I get signal 64
。。。。。
阅读全文
0 0
- linux 进程通讯之信号
- Linux 进程间通讯之信号方式
- Linux 进程间通讯之信号方式
- Linux进程通讯:信号(signal)
- Linux进程通讯:管道通讯、信号通讯、共享内存
- linux进程之间通讯常用信号
- Linux系统进程间通讯-信号
- linux 之进程信号
- Linux笔记_进程通讯——信号通讯
- linux进程通讯之信号量
- linux 进程通信之信号
- linux进程通信之信号
- Linux进程通信之信号
- Linux进程通信之信号
- linux 进程通信之 信号
- Linux进程通信之信号
- linux进程通信之信号
- Linux进程通信之信号
- 软件设计要求—“高内聚低耦合”
- Netty学习之旅(三)(分隔符和定长解码器)
- 利用数据报套接字实现数据传输及文件传输
- 手机号码脱敏处理
- celery的坑
- linux 进程通讯之信号
- (四)Eclipse下javaAPI操作HDFS
- 【Spring】OpenSessionInViewFilter解决Hibernate懒加载异常
- opencv 双目摄像头标定
- react native学习笔记12——RefreshControl下拉刷新
- 常用java虚拟机参数(跟踪垃圾回收--读懂虚拟机日志)
- Spring、SpringMVC、Mybatis三大框架整合步骤
- 第二周项目2 程序的多文件组织
- js table rootpath