死在山野的风里,活在自由的梦里
本专栏参考教材是四川轻化工大学陈年老师的linux实验指导手册(含学习通的一些程序笔记)。
掌握Linux环境下进程和进程间通信的概念、相关系统调用使用、多进程编程基本方法,初步掌握进程间通信的主要方式与编程方法。
2、实验工具及环境
Linux系统网络环境或单机,C编译环境。
3、实验计划学时
4学时上机实际操作。
4、实验内容及操作步骤
23-4.c
vfork()可让子进程先运行
#include
#include
#include
#include
#include
int main(void)
{
int data = 0;
pid_t pid;
int choose = 0;
while ((choose = getchar()) != 'q')
{
switch (choose)
{
case '1':
pid = fork();
if (pid < 0)
{
printf("Error !\n");
}
if (pid == 0)
{
data++;
exit(0);
}
wait(NULL);
if (pid > 0)
{
printf("data is %d\n", data);
}
break;
case '2':
pid = vfork();
if (pid < 0)
{
perror("Error !\n");
}
if (pid == 0)
{
data++;
exit(0);
}
wait(NULL);
if (pid > 0)
{
printf("data is %d\n", data);
}
break;
default:
break;
}
}
}
// 实现一个程序启动另一个程序后自身仍然在运行,即在子进程中加载执行其他程序而父进程等待子进程结束后才结束
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
/*接受键盘输入命令字符*/
pid_t pid;
pid = fork(); /*创建子进程*/
if (pid < 0)
{
printf("创建失败");
}
else if (pid == 0)
{
sleep(1);
execl("/bin/pwd", "pwd", NULL);
}
else
{
/*等待子进程信息*/
int status;
wait(&status);
/*继续父进程的执行*/
if (WIFEXITED(status) == 1)
{
printf("ha ha\n");
}
}
}
·管道文件的测试程序开始
·管道文件测试正在进行
·管道通信测试结束
接收进程收到信息后将它们送到标准输出文件上。
// 编写一段C语言程序使其完成:父子进程通过无名管道传递三条消息:
#include //用于main函数
#include
#include //用于pid_t
#include
#include
#include //用于close,read,write,fork
#define BUFFSIZ sizeof("管道文件的测试程序开始")
int main()
{
char message[3][BUFFSIZ] = {"管道文件的测试程序开始", "管道文件测试正在进行","管道通信测试结束"};
int i;
int fd[2]; //定义管道两端的描述符,有两个
pipe(fd); //创建管道
// printf("fd[0]:%d\n", fd[0]); //打印读端的fd
// printf("fd[1]:%d\n", fd[1]); //打印写端的fd
pid_t pid; //定义一个pid来接收fork的返回值
pid = fork();
if (pid < 0)
{
printf("创建失败");
exit(2);
}
//父进程
if (pid > 0)
{
close(fd[0]);
for (i = 0; i < 3; i++)
{
sleep(1);
if (write(fd[1], message[i], BUFFSIZ) != -1)
{
printf("message sent by parent:[%s]\n", message[i]);
fflush(stdout);
}
else
{
printf("写入错误");
exit(5);
}
}
}
//子进程
if (pid == 0)
{
close(fd[1]);
for (i = 0; i < 3; i++)
{
if (read(fd[0], message[i], BUFFSIZ) != -1)
{
printf("message received by child:[%s]\n", message[i]);
fflush(stdout);
}
else
{
printf("读出错误");
exit(4);
}
}
}
}
23-3.c
// 利用Linux / UNIX的软中断信号,编写一段C语言程序完成:显示数字1到100,在程序运行中如果捕获到一个SIGINT信号,
// 则转去执行一段显示当前系统时间的程序。在编程中要考虑到信号被复位的情况,使程序能够实现多次被打断却多次的恢复执行。
#include
#include
#include
#include
#include
#include
#include
void fun(int sig){
if(sig==SIGINT){
time_t sec = time(NULL);
struct tm t = *localtime(&sec);
printf("当前时间:%d:%d:%d\n", t.tm_hour, t.tm_min, t.tm_sec);
}
}
int main(int argc, char *argv[])
{
int i;
signal(SIGINT, fun); //执行新的函数
for(i=1;i<10;i++)
{
sleep(1);
printf("i:%d\n",i);
}
}
23-5.c
#include
#include
#include
#include
int main()
{
pid_t pid;
pid = fork();
if (pid < 0)
{
printf("创建失败");
}
//父进程
if (pid > 0)
{
printf("这是父进程,其pid为%d\n", getpid());
sleep(1); //让子进程1先输出
pid_t pid2;
pid2 = fork();
if (pid2 == 0)
{
printf("这是子进程2,其pid为%d,", getpid());
printf("其父进程pid为%d\n", getppid());
}
sleep(1); //让父进程运行慢一点,不要让子进程2的ppid变成1
}
//子进程
if (pid == 0)
{
printf("这是子进程1,其pid为%d,", getpid());
printf("其父进程pid为%d\n", getppid());
execl("/bin/pwd", "pwd", NULL); //执行外部命令
}
}
23-6.c
#include //用于main函数
#include
#include //用于pid_t
#include
#include
#include //用于close,read,write,fork
int main() //不含参数
{
char buf[32] = {0};
int fd[2]; //定义管道两端的描述符,有两个
pipe(fd); //创建管道
printf("fd[0]:%d\n", fd[0]); //打印读端的fd
printf("fd[1]:%d\n", fd[1]); //打印写端的fd
pid_t pid; //定义一个pid来接收fork的返回值
pid = fork();
if (pid < 0)
{
printf("创建失败");
}
//父进程
if (pid > 0)
{
write(fd[1], "hello", 5);
sleep(2);
read(fd[0], buf, 32);
printf("父进程收到:%s\n", buf);
}
//子进程
if (pid == 0)
{
read(fd[0], buf, 32);
printf("子进程收到:%s\n", buf);
sleep(1);
write(fd[1], "hi", 2);
}
}