linux 信号和管道,linux进程的信号通信与进程的管道通信

1.同步和互斥:进程互斥是进程之间发生的一种间接性作用,一般是程序不希望的。通常的情况是两个或两个以上的进程需要同时访问某个共享变量。我们一般将发生能够问共享变量的程序段成为临界区。两个进程不能同时进入临界区,否则就会导致数据的不一致,产生与时间有关的错误。解决互斥问题应该满足互斥和公平两个原则,即任意时刻只能允许一个进程处于同一共享变量的临界区,而且不能让任一进程无限期地等待。程同步是进程之间直接的相互作用,是合作进程间有意识的行为典型的例子是公共汽车上司机与售票员的合作。

0818b9ca8b590ca3270a3433284dd417.png

2.信号量和管道:信号量(semaphore)是解决同步互斥问题较为通用的方法,也称为红绿灯,本质上信号量就是一个计数器,用来记录波哥资源(如共享主存)的存储情况,维护信号量的状态是linux内核操作系统而不是用户进程,信号量主要提供对进程共享资源访问控制的手段,用来保护共享资源。而信号(signal)则是提供简单的处理异步事件的方法,即软中断通信。

管道是单向的字节流,它将某个进程的标准输出连接到另一个进程的标准输入。管道和有名管道是最早的进程间通信机制之一,管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。管道和有名管道的读写规则是在程序中应用它们的关键。管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,单独构成一种文件系统,并且只存在与内存中。数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

3.进程的信号通信:

用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘的中断信号(ctrl + c)捕捉到中断信号后父进程用系统调用kill()向两个子进程发送信号,子进程捕捉到信号后分别输出信息后终止,父进程等待两个子进程终止后同样输出信息终止。

#include

#include

#include

#include

#include

int mark;

void stop();

void waiting();

void keep_me_alive(int signal)

{

//printf("child alive\n");

}

int main()

{

pid_t p, p1, p2;

//signal(SIGINT, stop);

while((p1 = fork()) == -1);

if(p1 > 0)

{

while((p2 = fork()) == -1);

if(p2 == 0)

{

/* child process 2 */

mark = 1;

signal(SIGINT, keep_me_alive);

signal(12, stop);

waiting();

printf("child process 2 is killed by parent!\n");

exit(0);

}

else{

/*parent process */

mark = 1;

signal(SIGINT, stop);//捕获键盘中断信号

waiting();

kill(p1, 10);//10,12 是用户自定义信号

kill(p2, 12);

while(p = waitpid(-1, NULL, 0) > 0);

printf("parent process is killed\n");

exit(0);

}

}

/*child process 1 */

else{

mark = 1;

signal(SIGINT, keep_me_alive);

signal(10, stop);

waiting();

printf("child proces 1 is killed by parent!\n");

exit(0);

}

}

void waiting()

{

while(mark != 0);

}

void stop()

{

mark = 0;

}

4.进程的管道通信

实现进程的管道通信:父进程使用系统调用pipe()建立一个管道,创建两个子进程p1和p2,分别向管道发一条消息后结束。

#include

#include

#include

#include

#include

pid_t pid, pid2;

int main()

{

int fd[2];

char outpipe[100], inpipe[100];

pipe(fd);

while((pid = fork()) == -1 );

if(pid == 0)

{

lockf(fd[1], 1, 0);

sprintf(outpipe, "child's pid  %d %s", getpid(), "is sending a message to parent !\n");

write(fd[1], outpipe, 50);

sleep(5);

lockf(fd[1], 0, 0);

exit(0);

}

else

{

while((pid2 = fork()) == -1);

if(pid2 == 0)

{

lockf(fd[1], 1, 0);//锁定文件,实现进程互斥 sprintf(outpipe, "child's pid  %d %s", getpid(), "is sending a message to parent !\n"); write(fd[1], outpipe, 50); sleep(5); lockf(fd[1], 0, 0); exit(0); } else { wait(0); read(fd[0], inpipe, 50); printf("%s\n", inpipe); wait(0); read(fd[0], inpipe, 50); printf("%s\n", inpipe); exit(0); } } return 0; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值