linux环境下父进程子进程异步问题

damahayucalifornia 2011-12-31 08:42:29
各位大侠,小弟学完操作系统,感觉学的也不差啊,但现在老师让做课程设计,题目是在Linux环境下编程,然后就焦虑了。之前学的时候也有看过一些linux内核方面的书,但看的云里雾里的,坚持了一段时间后由于其他课程太多,也就放了下来,结果现在就悲剧了,虽然借了好几本书狂翻资料,但还是感觉有点摸不到头绪,我觉的这东西,要是对linux内核机制有一定的了解的话还是很容易的,但现在关键是没有那么多时间让我去看,恐怕到时不能完成,所以请大家帮我指点指点该如何做,如果能给出相应的源程序当然更好!到时分一定送上;
下面是我的题目:
父进程和子进程通过信号实现异步合作
在Linux环境下用C语言编程实现,使用用户自定义的信号SIGUSR1由父进程发给子进程,SIGUSR2由子进程发给父进程;父进程和子进程各自从终端接收一个字符串,完成后用kill调用发送信号,接收方接收到信号后,显示对方的进程号及字符串。利用信号方式(Signal(SIGCHLD,SIG_IDN))使父进程不必等待子进程结束,且不产生"ZOMBIE".
拜托了!
...全文
404 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Richardkaola 2012-01-01
  • 打赏
  • 举报
回复
fork()得到一个子进程。
程序先进入 父进程的default ,遇到 sleep 阻塞后进入到 子进程的 case 0 同样sleep阻塞回到 父进程的default(我认为你这里的sleep没意义)。接下来 scanf IO 阻塞,但另一边也还阻塞着(就算sleep阻塞结束接下来又有一个scanf 的 IO 阻塞)
然后 现在你输入的 信息 会输入到 父进程的 ps 中。然后你给子进程发送了一个信号:kill(pid,SIGUSR1); 子进程收到信号后调用了 c_action 。不过 多进程的地址空间是独立的,子进程里的ps没有定义, 所以应该会输出 空串。同理 子进程的 cs 虽然你赋值了,但是 父进程执行 信号处理函数时,是调用自己地址空间里的cs,自然也应该是空串。
damahayucalifornia 2011-12-31
  • 打赏
  • 举报
回复
题目要求完成输入字符串发送,接收方接收到并予以相应(输出发送方的pid和字符串“),而且显示的是发送方的进程号,不是接受方的进程号
那按照1楼的说法我是否可以定义两个全局变量char ps[100]; char cs[100];而且把pid和ppid也定义成全局变量;
然后再做一下修改:
case:0:
....
printf("please input the string from child:\n");
scanf("%s",cs);
kill(ppid,SIGUSR2);
break;
default:
....
printf("please input the string from parent:\n");
scanf("%s",ps);
kill(pid,SIGUSR1);
...
}
然后再对p_action和c_action修改
void p_action(int sig)
{
printf("parent process %d recieve SIGUSR2 signal,signo is %d\n",getpid(),signo);
printf("the sender(son) process's pid is %d\n",pid);
printf("the chararray from child process is:%s\n",cs);
}
void c_action(int sig)
{
printf("child process %d recieve SIGUSR1 signal,signo is %d\n",getpid(),signo);
printf("the sender(parent) process's pid is %d\n",ppid);
printf("the chararray from parent process is:%s\n",ps);
}
高人们快来指点指点啊
wesleyluo 2011-12-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 mscf 的回复:]

C/C++ code

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


void p_action(int signo){
printf("parent process %d recieve SIGUSR2 signal,signo is %d\n",getpid(),signo);
}

void c_acti……
[/Quote]
+
薛定谔之死猫 2011-12-31
  • 打赏
  • 举报
回复

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


void p_action(int signo){
printf("parent process %d recieve SIGUSR2 signal,signo is %d\n",getpid(),signo);
}

void c_action(int signo){
printf("child process %d recieve SIGUSR1 signal,signo is %d\n",getpid(),signo);
}

int main(int argc, char *argv[])
{
int pid,ppid;
signal(SIGCHLD,SIG_IGN);
switch(pid=fork()){
case -1:
printf("create child process error!\n");
break;
case 0:
signal(SIGUSR1,c_action);
ppid=getppid();
sleep(5);
printf("child process %d send signal %d to process %d...\n",getpid(),SIGUSR2,ppid);
kill(ppid,SIGUSR2);
break;
default:
signal(SIGUSR2,p_action);
sleep(2);
printf("parent process %d send signal %d to process %d...\n",getpid(),SIGUSR1,pid);
kill(pid,SIGUSR1);
pause();
break;
}
return 0;
}
damahayucalifornia 2011-12-31
  • 打赏
  • 举报
回复

大家抽点时间帮小弟看下,确实是费解,头疼,我把楼上的程序按要求修改以后发现一个问题,我定义的两个字符串全局变量ps和cs再main函数中用scanf函数不能输入,不起作用。。。。按理说,全局变量应该是在整个文件内有效啊,但是,为什么,为什么,为什么,scanf函数不起作用?????查了很多资料未果,,心里很是纠结。。。。大家帮忙看看吧 如果不设全局变量,那又该如何在接收方的函数中显示发送方输入的字符串呢????
下面是我修改后的源程序
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int pid,ppid;
char ps[100];
char cs[100];
void p_action(int signo){
printf("parent process %d recieve SIGUSR2 signal,signo is %d\n",getpid(),signo);
printf("the sender(child) process's pid is %d\n",pid);
printf("the chararray from child process is:%s\n",cs);
}

void c_action(int signo){
printf("child process %d recieve SIGUSR1 signal,signo is %d\n",getpid(),signo);
printf("the sender(parent) process's pid is %d\n",ppid);
printf("the chararray from parent process is:%s\n",ps);
}

int main(int argc, char *argv[])
{

signal(SIGCHLD,SIG_IGN);
switch(pid=fork()){
case -1:
printf("create child process error!\n");
break;
case 0:
signal(SIGUSR1,c_action);
ppid=getppid();

sleep(5);
printf("please input the string from child:\n");
scanf("%s",cs);
printf("child process %d send signal %d to process %d...\n",getpid(),SIGUSR2,ppid);
kill(ppid,SIGUSR2);
break;
default:
signal(SIGUSR2,p_action);

sleep(2);
printf("please input the string from parent:\n");
scanf("%s",ps);
printf("parent process %d send signal %d to process %d...\n",getpid(),SIGUSR1,pid);
kill(pid,SIGUSR1);
pause();
break;
}
return 0;
}
damahayucalifornia 2011-12-31
  • 打赏
  • 举报
回复
是,这个明白,signal(SIGCHLD,SIG_IGN);是消除僵死进程。但我想知道的是,我那样改那个程序可否?
qq120848369 2011-12-31
  • 打赏
  • 举报
回复

POSIX.1-2001 specifies that if the disposition of SIGCHLD is set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD (see sigaction(2)), then
children that terminate do not become zombies and a call to wait() or waitpid() will block until all children have terminated, and then fail with
errno set to ECHILD. (The original POSIX standard left the behavior of setting SIGCHLD to SIG_IGN unspecified. Note that even though the default
disposition of SIGCHLD is "ignore", explicitly setting the disposition to SIG_IGN results in different treatment of zombie process children.)
Linux 2.6 conforms to this specification. However, Linux 2.4 (and earlier) does not: if a wait() or waitpid() call is made while SIGCHLD is being
ignored, the call behaves just as though SIGCHLD were not being ignored, that is, the call blocks until the next child terminates and then returns
the process ID and status of that child.



看完这个应该都懂了。
Linux网络编程(总共41集) 讲解Linux网络编程知识,分以下四个篇章。 Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口) 02TCPIP基础(二) 最大传输单元(MTU)/路径MTU 以太网帧格式 ICMP ARP RARP 03TCPIP基础(三) IP数据报格式 网际校验和 路由 04TCPIP基础(四) TCP特点 TCP报文格式 连接建立三次握手 连接终止四次握手 TCP如何保证可靠性 05TCPIP基础(五) 滑动窗口协议 UDP特点 UDP报文格式 Linux网络编程之socket编程篇 06socket编程(一) 什么是socket IPv4套接口地址结构 网络字节序 字节序转换函数 地址转换函数 套接字类型 07socket编程(二) TCP客户/服务器模型 回射客户/服务器 socket、bind、listen、accept、connect 08socket编程(三) SO_REUSEADDR 处理多客户连接(process-per-conection) 点对点聊天程序实现 09socket编程(四) 流协议与粘包 粘包产生的原因 粘包处理方案 readn writen 回射客户/服务器 10socket编程(五) read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与SIGCHLD信号 12socket编程(七) TCP 11种状态 连接建立三次握手、连接终止四次握手 TIME_WAIT与SO_REUSEADDR SIGPIPE 13socket编程(八) 五种I/O模型 select 用select改进回射客户端程序 14socket编程(九) select 读、写、异常事件发生条件 用select改进回射服务器程序。 15socket编程(十) 用select改进第八章点对点聊天程序 16socket编程(十一) 套接字I/O超时设置方法 用select实现超时 read_timeout函数封装 write_timeout函数封装 accept_timeout函数封装 connect_timeout函数封装 17socket编程(十二) select限制 poll 18socket编程(十三) epoll使用 epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址结构 UNIX域字节流回射客户/服务 UNIX域套接字编程注意点 22socket编程(十七) socketpair sendmsg/recvmsg UNIX域套接字传递描述符字 Linux网络编程之进程间通信篇 23进程间通信介绍(一) 进程同步与进程互斥 进程间通信目的 进程间通信发展 进程间通信分类 进程间共享信息的三种方式 IPC对象的持续性 24进程间通信介绍(二) 死锁 信号量 PV原语 用PV原语解决司机与售票员问题 用PV原语解决民航售票问题 用PV原语解决汽车租赁问题 25System V消息队列(一) 消息队列 IPC对象数据结构 消息队列结构 消息队列在内核中的表示 消息队列函数 26System V消息队列(二) msgsnd函数 msgrcv函数 27System V消息队列(三) 消息队列实现回射客户/服务器 28共享内存介绍 共享内存 共享内存示意图 管道、消息队列与共享内存传递数据对比 mmap函数 munmap函数 msync函数 29System V共享内存 共享内存数据结构 共享内存函数 共享内存示例 30System V信号量(一) 信号量 信号量集结构 信号量集函数 信号量示例 31System V信号量(二) 用信号量实现进程互斥示例 32System V信号量(三) 用信号集解决哲学家就餐问题 33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35POSIX共享内存 POSIX共享内存相关函数 POSIX共享内存示例 Linux网络编程之线程篇 36线程介绍 什么是线程 进程与线程 线程优缺点 线程模型 N:1用户线程模型 1:1核心线程模型 N:M混合线程模型 37POSIX线程(一) POSIX线程库相关函数 用线程实现回射客户/服务器 38POSIX线程(二) 线程属性 线程特定数据 39POSIX信号量与互斥锁 POSIX信号量相关函数 POSIX互斥锁相关函数 生产者消费者问题 自旋锁与读写锁介绍 40POSIX条件变量 条件变量 条件变量函数 条件变量使用规范 使用条件变量解决生产者消费者问题 41一个简单的线程池实现 线程池性能分析 线程池实现 网络编程, Linux, 密码

18,829

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 专题技术讨论区
社区管理员
  • 专题技术讨论区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧