现在的位置: 首页 > 综合 > 正文

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

2013年10月20日 ⁄ 综合 ⁄ 共 2371字 ⁄ 字号 评论关闭

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

[转载]操作系统:进程的同步与互斥

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

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

3.进程的信号通信:

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

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<sys/types.h>
#include<stdlib.h>

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<unistd.h>
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>

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;
}

抱歉!评论已关闭.