Linux高级编程实验(30个)

文章目录

    • 1)输出Linux下的c也不是太难嘛!在linux下编辑,编译,运行
    • 2)编写一个简单地c语言程序,根据输入的两个整数求平均值并且在终端输出,通过gcc编译器得到它的汇编程序文件。
    • 3)编写一个c语言程序,打印输出所有的“水仙花数”
    • 4)创建文件init_test.c,并用valgrind检测内存错误,并把代码修改正确
    • 5)创建文件test2.c,并用valgrind检测内存错误,并把代码修改正确;
    • 6)创建文件test3.c,并用valgrind检测内存错误,并把代码修改正确;
    • 7)创建文件test4.c,并用valgrind检测内存错误,并把代码修改正确;
    • 8)创建文件test5.c,并用valgrind检测内存错误,并把代码修改正确;
    • 9)创建文件file1,写入字符串“abcdefghijklmn”; 创建文件file2,写入字符串“ABCDEFGHIJKLMN”;读取file1中的内容,写入file2,使file2中的字符串内容为“ ABCDEFGHIJKLMNabcdefghijklmn”
    • 10)创建新文件,该文件具有用户读写权限。采用dup/dup2/fcntl复制一个新的文件描述符,通过新文件描述符向文件写入“class_name”字符串;通过原有的文件描述符读取文件中的内容,并且打印显示;
    • 11)输入文件名称,能够判断文件类型,判断实际用户对该文件具有哪些存取权限;要求打印出文件类型信息,inode节点编号,链接数目,用户id,组id,文件大小信息;修改文件的权限为当前用户读写,组内用户读写,组外用户无权限。
    • 12)新建文件,设置文件权限屏蔽字为0;建立该文件的硬链接文件,打印硬链接文件的inode节点号和文件大小;建立该文件的软链接文件,打印软链接文件的inode节点号和文件大小;打印软链接文件中的内容;打印源文件的inode节点号,文件大小和链接数目;调用unlink对源文件进行操作,打印源文件链接数目;
    • 13)新建/home/user目录;把当前工作路径移至/home/user目录;打印当前工作路径;
    • 14)编写程序完成以下功能:递归遍历/home目录,打印出所有文件和子目录名称及节点号。判断文件类型,如果是子目录,继续进行递归遍历,直到遍历完所有子目录为止。
    • 15)打印当前所有环境变量的值;添加新的环境变量NEWENV=first;修改环境变量NEWENV的值为second;打印环境变量NEWENV的值。
    • 16)打印字符串“hello world!”,在打印字符串“hello world!”前调用三次fork,分析打印结果。
    • 17)在子进程中打开文件file1,写入自己的“班级_姓名_学号”,父进程读取file1中的内容,并且打印显示。在父进程中获取已经结束的子进程的状态信息,打印该信息,并且打印结束的子进程的进程号。
    • 18)在父进程中定义变量n,在子进程中对变量n进行++操作;并且打印变量n的值,打印子进程pid;在父进程中打印变量n的值,并且打印父进程pid。要求分别用fork和vfork创建子进程。
    • 19)创建子进程一,在子进程中递归打印/home目录中的内容(用exec系列函数调用第二次实验中的代码完成此功能);子进程结束的时候完成以下功能:打印字符串“Child process exited!”。打印子进程标识符,打印父进程标识符。创建子进程二, 打印子进程运行环境中环境变量“USER”的值,通过exec系列中的某个函数设置子进程”USER”环境变量值为“zhangsan”,并且让该子进程完成以下命令:“ls –li /home”.
    • 20)编程实现以下功能:主线程实现以下功能: ① 定义全局变量key;② 创建两个线程;③ 如果线程正常结束,得到线程的结束状态值,并打印;线程一完成以下操作:① 设置全局变量key的值为字符串“hello world”;② 打印3次字符串“当前线程ID:key值”;③ 接收到线程二发送的取消请求信号后退出;④ 结束的时候打印字符串“thread1 ,exited!:key值”;线程二完成以下操作:① 设置key值为6;② 给线程一发送取消请求信号;
    • 21)用多线程实现生产者消费者,至少有两个消费者和两个生产者
    • 22)利用匿名管道实现父子进程间通信,要求父进程发送字符串“hello child”给子进程;子进程收到父进程发送的数据后,给父进程回复“hello farther”;父子进程通信完毕,父进程依次打印子进程的退出状态以及子进程的pid
    • 23)利用匿名管道实现兄弟进程间通信,要求兄进程发送字符串“This is elder brother ,pid is (兄进程进程号)”给第进程;第进程收到兄进程发送的数据后,给兄进程回复“This is younger brother ,pid is(第进程进程号)”;
    • 24)利用有名管道文件实现进程间通信,要求写进程向有名管道文件写入10次“hello world”;读进程读取有名管道文件中的内容,并依次打印。
    • 25)进程A向进程B发送SIGUSR1信号;进程B收到信号后,打印字符串“receive SIGUSR1”;要求用kill函数和signal函数实现以上功能;
    • 26)调用setitimer函数分别触发SIGALRM信号,SIGVTALRM信号,SIGPROF信号 ;(可以由多进程分别触发每个信号)编写信号安装函数,在该函数内部能判断接受到的是什么信号,并把信号打印出来。
    • 27)进程A向进程B发送SIGUSR1信号;进程B收到信号后,打印字符串“receive SIGUSR1”;要求用sigqueue函数和sigaction函数实现以上功能;
    • 28)进程A向进程B发送信号,该信号的附带信息为一个值为20的整数;进程B完成接收信号的功能,并且打印出信号名称以及随着信号一起发送过来的整形变量值。
    • 29)创建共享内存,写进程通过键盘不断向内存写入“hello world”;如果结束写操作,则通过键盘输入“end”;读进程从共享内存读取数据,并打印。直到读到“end”为止。
    • 30)进程A向消息队列发送消息“hello,world”,进程B从消息队列读取消息,并打印。进程C向消息队列发送“自己在姓名”,进程D从消息队列中取出姓名字符串,并打印

1)输出Linux下的c也不是太难嘛!在linux下编辑,编译,运行

(1)创建test.c文件,然后编辑 test.c文件
在这里插入图片描述
(2)编写程序,保存退出

#include<stdio.h>int main(){printf("Linux下的C语言不是太难嘛!");printf("Linux下的C语言不是太难嘛!");return 0;
}

(3)输入 gcc test.c -o test编译文件,并生成test可执行程序文件
(4)输入 ./test 运行 test
在这里插入图片描述

2)编写一个简单地c语言程序,根据输入的两个整数求平均值并且在终端输出,通过gcc编译器得到它的汇编程序文件。

#include <stdbool.h>
#include<stdio.h>
int main() {double a,b;double c;printf("请输入两个数值:");scanf("%lf%lf",&a,&b);c=(a+b)/2;printf("%.2lf",c);return 0;
}

3)编写一个c语言程序,打印输出所有的“水仙花数”

#include<stdio.h>
int main(){int a,b,c,d;a = b = c = 0;printf("请输入你要输入的范围:\n");scanf("%d",&d);for(int i = 100; i <d; i++) {a = i % 10;b = (i / 10) % 10;c = i / 100;if((a*a*a + b*b*b + c*c*c) == i) {printf("%d\n" , i);}}
}

4)创建文件init_test.c,并用valgrind检测内存错误,并把代码修改正确

(1)创建文件init_test.c
在这里插入图片描述


在这里插入图片描述

(2)用valgrind检测内存错误
在这里插入图片描述
(3)修改代码
在这里插入图片描述

#include<stdio.h>
int main(void){
int x;
scanf("%d",&x);
if(x==0)
printf("x is zero");
else
printf("x is not zero");
return 0;
}

(4)Valgrind验证
在这里插入图片描述

5)创建文件test2.c,并用valgrind检测内存错误,并把代码修改正确;

(1)创建文件test2.c
在这里插入图片描述

在这里插入图片描述
(2)用valgrind检测内存错误
在这里插入图片描述

(3)修改代码
在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
void fun(){int *p=(int *)malloc(10*sizeof(int));p[9]=0;free(p);}int main(int argc,char* argv[])
{fun();
return 0;
}  

(4)valgrind验证代码
在这里插入图片描述

6)创建文件test3.c,并用valgrind检测内存错误,并把代码修改正确;

(1)创建test3.c文件

在这里插入图片描述
(2)用valgrind检测内存错误
在这里插入图片描述
(3)修改代码
在这里插入图片描述

#include<stdlib.h>
#include<stdio.h>int main(int argc,char *argv[])
{int i=0;int len=4;int* pt=(int *)malloc(len*sizeof(int));int* p=pt;for( i=0;i<len-1;i++){*p++;}*p=5;
printf("the value of p equal:%d",*p);
free(pt);
return 0;}

(4) valgrind测试
在这里插入图片描述

7)创建文件test4.c,并用valgrind检测内存错误,并把代码修改正确;

(1)创建test4.c文件

在这里插入图片描述
(2)用valgrind检测错误
在这里插入图片描述
(3)修改代码
在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main(int argc, char *argv[])
{char x[50];int i;for(i=0;i<50;i++)
{x[i]=i+1;
}strncpy(x+20,x,20);//OKstrncpy(x+21,x,21);strncpy(x,x+20,20); //okstrncpy(x,x+20,20);x[39]='\0';strcpy(x,x+20);x[39]=39;x[40]='\0';strcpy(x,x+21);return 0;}

(4) valgrind测试
在这里插入图片描述

8)创建文件test5.c,并用valgrind检测内存错误,并把代码修改正确;

(1)创建test5.c文件
在这里插入图片描述
(2)用valgrind进行测试
在这里插入图片描述
(3)修改代码

#include<stdlib.h>
#include<stdio.h>int main(int argc,char *argv[]){int i;char* p=(char*)malloc(10);char* pt=p;for(i=1;i<10;i++){p[i]='z';}pt[1]='x';free(pt);return 0;
}

(4)用 valgrind验证代码正确
在这里插入图片描述

9)创建文件file1,写入字符串“abcdefghijklmn”; 创建文件file2,写入字符串“ABCDEFGHIJKLMN”;读取file1中的内容,写入file2,使file2中的字符串内容为“ ABCDEFGHIJKLMNabcdefghijklmn”

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>int main() {int fd1,fd2;fd1=open("file1",O_CREAT|O_RDWR,S_IRWXU);if(fd1< 0) {perror("open :");printf("errno is:%d \n",errno);} elseprintf("open ok\n");fd2=open("file2",O_CREAT|O_RDWR,S_IRWXU);if(fd2< 0) {perror("open:");printf("errno is:%d \n,errno");} elseprintf("open OK \n");int fdw1,fdw2;fdw1=write(fd1,"abcdefghijklmn",15);printf("fdw1:%d\n",fdw1);if(fdw1!=15) {perror("write fd1:");} elseprintf("write OK\n");lseek(fd2,16,SEEK_SET);char buf[20]="ABCDEFGHIJKLMN";fdw2=write(fd2,buf,20);if(fdw2<0)perror ("write fd2:");elseprintf("write OK\n");lseek (fd1,0,SEEK_SET);lseek(fd2,0,SEEK_SET);char re[28];read(fd1,re,14);write(fd2,re,14);close(fd1);close(fd2);return 0;
}

10)创建新文件,该文件具有用户读写权限。采用dup/dup2/fcntl复制一个新的文件描述符,通过新文件描述符向文件写入“class_name”字符串;通过原有的文件描述符读取文件中的内容,并且打印显示;

#include<stdio.h>
#include<string.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>int main() {int fd1,fd2;fd1=open("file",O_RDWR|O_CREAT,0644);fd2=dup(fd1);char str[30];char name[30]="class_name";lseek(fd2,0,SEEK_SET);write(fd2,name,30);lseek(fd1,0,SEEK_SET);read(fd1,str,30);printf("%s",str);close(fd1);return 0;
}

11)输入文件名称,能够判断文件类型,判断实际用户对该文件具有哪些存取权限;要求打印出文件类型信息,inode节点编号,链接数目,用户id,组id,文件大小信息;修改文件的权限为当前用户读写,组内用户读写,组外用户无权限。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc,char *argv[]) {if(argc < 2) {printf("Please input the filename!\n");return 0;}struct stat statbuf;int i;for(i = 1; i < argc; i++) {if(lstat(argv[i],&statbuf) < 0)perror("lstat");char *buf;if(S_ISREG(statbuf.st_mode))buf = "Regular file!";else if(S_ISDIR(statbuf.st_mode))buf = "Directory file!";else if(S_ISCHR(statbuf.st_mode))buf = "Char file!";elsebuf = "Other file!";printf("The %s is:%s\n",argv[i],buf);printf("The %s mode is:%d\n",argv[i],statbuf.st_mode);printf("The %s inode is:%d\n",argv[i],statbuf.st_ino);printf("The %s uid is:%d\n",argv[i],statbuf.st_uid);printf("The %s gid is:%d\n",argv[i],statbuf.st_gid);printf("The %s size is:%d\n",argv[i],statbuf.st_size);printf("The %s link num is:%d\n",argv[i],statbuf.st_nlink);}for(i = 1; i < argc; i++) {if(access(argv[i],R_OK))printf("The user can read the %s\n",argv[1]);else if(access(argv[i],W_OK))printf("The user can write the %s\n",argv[1]);else if(access(argv[i],X_OK))printf("The user can read and write the %s\n",argv[1]);}for(i = 1; i < argc; i++) {if(chmod(argv[i],0660) < 0)perror("chmod");elseprintf("The file.mode chmod successful!\n");}return 0;
}

12)新建文件,设置文件权限屏蔽字为0;建立该文件的硬链接文件,打印硬链接文件的inode节点号和文件大小;建立该文件的软链接文件,打印软链接文件的inode节点号和文件大小;打印软链接文件中的内容;打印源文件的inode节点号,文件大小和链接数目;调用unlink对源文件进行操作,打印源文件链接数目;

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
int main() {umask(0);struct stat statbuf;int fd = open("file",O_CREAT|O_RDWR);if(fd < 0)perror("open");char *str = "hello world";if(write(fd,str,strlen(str)) < 0)perror("write");link("./file","./hard_link");if(lstat("hard_link",&statbuf) < 0)perror("lstat");printf("The hard_link's inode is: %d\n",statbuf.st_ino);printf("The hard_link's size is: %d\n",statbuf.st_size);symlink("file","sort_link");if(lstat("sort_link",&statbuf) < 0)perror("lstat");printf("The sort_link's inode is: %d\n",statbuf.st_ino);printf("The sort_link's size is: %d\n",statbuf.st_size);char buf[4];readlink("sort_link",buf,4);printf("The sort_link is: %s\n",buf);if(lstat("file",&statbuf) < 0)perror("lstat");printf("The file's inode is: %d\n",statbuf.st_ino);printf("The file's size is: %d\n",statbuf.st_size);printf("The frist linknum is: %d\n",statbuf.st_nlink);unlink("file");if(lstat("file",&statbuf) < 0)perror("lstat");printf("The second linknum is: %d\n",statbuf.st_nlink);close(fd);return 0;
}

13)新建/home/user目录;把当前工作路径移至/home/user目录;打印当前工作路径;

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
int main() {char str[128];if(getcwd(str,128) < 0)perror("getwcd");elseprintf("The workdir is:%s\n",str);if(mkdir("/home/user",0666) < 0)perror("mkdir");elseprintf("The dir create successfully!\n");if(chdir("/home/user") < 0)perror("chdir");else {getcwd(str,128);printf("The workdir is:%s\n",str);}rmdir("/home/user");return 0;
}

14)编写程序完成以下功能:递归遍历/home目录,打印出所有文件和子目录名称及节点号。判断文件类型,如果是子目录,继续进行递归遍历,直到遍历完所有子目录为止。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>void show(char *path) {DIR *dir;char str[128];struct dirent *dirp;struct stat statbuf;dir = opendir(path);if(dir) {while((dirp = readdir(dir)) != NULL) {sprintf(str,"%s/%s",path,dirp->d_name);if(lstat(str,&statbuf) < 0)perror("lstat");if(dirp->d_name[0] == '.')continue;if(S_ISDIR(statbuf.st_mode)) {show(str);printf("The dirent's name is: %s\n",dirp->d_name);printf("The dirent's inode is: %d\n",dirp->d_ino);} else {printf("The file's name is: %s\n",dirp->d_name);printf("The file's inode is: %d\n",dirp->d_ino);}}} elseperror("opendir");closedir(dir);
}int main() {show("/home");return 0;
}

15)打印当前所有环境变量的值;添加新的环境变量NEWENV=first;修改环境变量NEWENV的值为second;打印环境变量NEWENV的值。

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
extern char **environ;int main() {char **env = environ;while(*env) {printf("The env is: %s\n",*env);env++;}putenv("NEWENV=first");char *str;str = getenv("NEWENV");printf("The NEWENV is: %s\n",str);if(setenv("NEWENV","second",1) < 0)perror("setenv");str = getenv("NEWENV");printf("The NEWENV is: %s\n",str);return 0;
}

16)打印字符串“hello world!”,在打印字符串“hello world!”前调用三次fork,分析打印结果。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>int main()
{fork();fork();fork(); printf("hello world!!!\n");return 0;
}

17)在子进程中打开文件file1,写入自己的“班级_姓名_学号”,父进程读取file1中的内容,并且打印显示。在父进程中获取已经结束的子进程的状态信息,打印该信息,并且打印结束的子进程的进程号。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
int main() {int fd,pid;fd = open("file",O_CREAT|O_RDWR,S_IRWXU);if(fd< 0)perror("open");pid = fork();if(pid  == 0) {printf("This is the child!\n");char str[128] = "class__name_× × × × ×";if(write(fd,str,128) < 0)perror("write");exit(5);} else {printf("This is the father!\n");char buf[128];int n,status;if(read(fd,buf,128) < 0)perror("read");printf("The buf is: %s\n",buf);if(wait(&status) < 0)perror("perror");if(WIFEXITED(status))n = WEXITSTATUS(status);elseprintf("wait error!\n");printf("The child's pid is: %d\n",pid);printf("The child exit status is: %d\n",n);}return 0;
}

18)在父进程中定义变量n,在子进程中对变量n进行++操作;并且打印变量n的值,打印子进程pid;在父进程中打印变量n的值,并且打印父进程pid。要求分别用fork和vfork创建子进程。

创建fork.c文件,编写代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {int n = 1;if(fork() == 0) {printf("This is child,the pid is%d\n",getpid());printf("The n is: %d\n",++n);} else {printf("This is father,the pid is%d\n",getpid());printf("The n is: %d\n",n);}return 0;
}

创建vfork.c文件

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {int n = 1;pid_t pid;pid = vfork();if(pid < 0)perror("vfork");else if(pid == 0) {printf("This is child,the child's pid is: %d\n",getpid());printf("The n is: %d\n",++n);exit(0);} else {printf("This is father,the father's pid is: %d\n",getpid());printf("The n is: %d\n",n);}return 0;
}

19)创建子进程一,在子进程中递归打印/home目录中的内容(用exec系列函数调用第二次实验中的代码完成此功能);子进程结束的时候完成以下功能:打印字符串“Child process exited!”。打印子进程标识符,打印父进程标识符。创建子进程二, 打印子进程运行环境中环境变量“USER”的值,通过exec系列中的某个函数设置子进程”USER”环境变量值为“zhangsan”,并且让该子进程完成以下命令:“ls –li /home”.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>void fun() {printf("\n");printf("Child process exited!!!\n");printf("The child's pid is: %d\n",getpid());printf("The father's pid is %d\n",getppid());printf("\n");
}int main() {pid_t pid;pid = vfork();if(pid <0)perror("vfork");else if(pid == 0) {printf("This is the child1 !!!\n");atexit(fun);if((execl("/home/wang/test/file/test6/test","test",NULL)) < 0) {perror("execl");exit(0);}} else {printf("This is the father !!!\n");if(vfork() == 0) {printf("This is the child2 !!!\n");printf("The child2's father's pid is: %d\n",getppid());char * env[] = {"USER=zhangsan",NULL};char *p;p = getenv("USER");if(p) {printf("The user is: %s\n",p);}system("ls -li /home");if((execle("/bin/env","env",NULL,env)) < 0)perror("execle");exit(1);}}return 0;
}

20)编程实现以下功能:主线程实现以下功能: ① 定义全局变量key;② 创建两个线程;③ 如果线程正常结束,得到线程的结束状态值,并打印;线程一完成以下操作:① 设置全局变量key的值为字符串“hello world”;② 打印3次字符串“当前线程ID:key值”;③ 接收到线程二发送的取消请求信号后退出;④ 结束的时候打印字符串“thread1 ,exited!:key值”;线程二完成以下操作:① 设置key值为6;② 给线程一发送取消请求信号;

创建 Thread_test.c文件,编写程序

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <pthread.h>
pthread_key_t key;void cleanup(void *arg) {printf("%s\n",(char *)arg);
}void *child_thread1(void *arg) {char *str = "Hello World";printf("The child_thread1 run!\n");printf("The thread id is: %d\n",syscall(SYS_gettid));if(pthread_setspecific(key,str) < 0)perror("pthread_setspecific");char *get_key = (char *)pthread_getspecific(key);printf("The thread1's key is: %s\n",get_key);pthread_cleanup_push(cleanup,"Thread1,exited!");pthread_cleanup_pop(1);
}void *child_thread2(void *arg) {int num = 6;printf("The child_thread2 run!\n");if(pthread_cancel((pthread_t)arg) < 0)perror("pthread_cancle");if(pthread_setspecific(key,(void *)num) < 0)perror("pthread_setspecific");int *get_key = (int *)pthread_getspecific(key);printf("The thread2's key is: %d\n",get_key);pthread_cleanup_push(cleanup,"Thread2,exited!");pthread_cleanup_pop(1);
}void *thread(void *arg) {pthread_t tid1,tid2;void *tret1,*tret2;printf("This is the main pthread!\n");if(pthread_key_create(&key,NULL) < 0)perror("phtread_key_create");if(pthread_create(&tid1,NULL,(void *)child_thread1,NULL) < 0)perror("pthread_create");pthread_join(tid1,&tret1);printf("The pthread1 exited is: %d\n",(long)tret1);if(pthread_create(&tid2,NULL,(void *)child_thread2,&tid1) < 0)perror("pthread_create");pthread_join(tid2,&tret2);printf("The pthread2 exited is: %d\n",(long)tret2);
}int main() {pthread_t id;if(pthread_create(&id,NULL,(void *)thread,NULL) < 0)perror("pthread_create");sleep(1);return 0;
}

21)用多线程实现生产者消费者,至少有两个消费者和两个生产者

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>#define BUFFER_SIZE	10
#define SEM_KEY		1234struct circle_buf {int r;int w;int buf[BUFFER_SIZE];
};int semid;
struct sembuf semaphore;
struct circle_buf cbuf;void writecbuf(struct circle_buf *cbuf, int val) {cbuf->buf[cbuf->w] = val;cbuf->w = (cbuf->w + 1) % BUFFER_SIZE;
}int readcbuf(struct circle_buf *pcbuf) {int value = pcbuf->buf[pcbuf->r];pcbuf->buf[pcbuf->r] = -1;pcbuf->r = (pcbuf->r + 1) % BUFFER_SIZE;return value;
}void outcbuf(struct circle_buf *pcbuf) {int i = 0;printf("缓冲区各单元的值:");for (i = 0; i < BUFFER_SIZE; ++i) {printf("%d%c", pcbuf->buf[i],(i == BUFFER_SIZE - 1) ? '\n' : ' ');}
}int initsembuf(void) {int sem = 0;if ((semid = semget(SEM_KEY, 3, IPC_CREAT | 0666)) >= 0) {sem = 1;semctl(semid, 0, SETVAL, sem);sem = BUFFER_SIZE;semctl(semid, 1, SETVAL, sem);sem = 0;semctl(semid, 2, SETVAL, sem);return 1;} else {return 0;}
}void pmutex(void) {semaphore.sem_num = 0;semaphore.sem_op = -1;semaphore.sem_flg = SEM_UNDO;semop(semid, &semaphore, 1);
}void vmutex(void) {semaphore.sem_num = 0;semaphore.sem_op = 1;semaphore.sem_flg = SEM_UNDO;semop(semid, &semaphore, 1);
}void pempty(void) {semaphore.sem_num = 1;semaphore.sem_op = -1;semaphore.sem_flg = SEM_UNDO;semop(semid, &semaphore, 1);
}void vempty(void) {semaphore.sem_num = 1;semaphore.sem_op = 1;semaphore.sem_flg = SEM_UNDO;semop(semid, &semaphore, 1);
}void pfull(void) {semaphore.sem_num = 2;semaphore.sem_op = -1;semaphore.sem_flg = SEM_UNDO;semop(semid, &semaphore, 1);
}void vfull(void) {semaphore.sem_num = 2;semaphore.sem_op = 1;semaphore.sem_flg = SEM_UNDO;semop(semid, &semaphore, 1);
}void sigend(int sig) {semctl(semid, 3, IPC_RMID);exit(0);
}void *productthread(void *arg) {int val = *(int *)arg;while (1) {pempty();pmutex();writecbuf(&cbuf, val);printf("生产者%d写入缓冲区的值=%d.\n", val, val);outcbuf(&cbuf);vmutex();vfull();}return NULL;
}void *consumerthread(void *arg) {int cid = *(int *)arg;int val = 0;while (1) {pfull();pmutex();val = readcbuf(&cbuf);printf("消费者%d取走的产品的值=%d.\n", cid, val);outcbuf(&cbuf);vmutex();vempty();}return NULL;
}int main(int argc, char *argv[]) {while (!initsembuf()) {;}signal(SIGINT, sigend);signal(SIGTERM, sigend);int i = 0;int ret = 0;int consnum = 0;int prodnum = 0;cbuf.r = 0;cbuf.w = 0;memset(cbuf.buf, 0, BUFFER_SIZE);printf("请输入生产者进程的数目:");scanf("%d", &prodnum);int *prosarg = (int *)malloc(prodnum * sizeof(int));pthread_t *prosid = (pthread_t *)malloc(prodnum * sizeof(pthread_t));printf("请输入消费者进程的数目:");scanf("%d", &consnum);int *consarg = (int *)malloc(consnum * sizeof(int));pthread_t *consid = (pthread_t *)malloc(consnum * sizeof(pthread_t));for (i = 0; i < prodnum; ++i) {prosarg[i] = i + 1;ret = pthread_create(&prosid[i], NULL, productthread,(void *)&prosarg[i]);printf("消费者prosid[%d] = %lu\n", i + 1, prosid[i]);if (ret != 0) {printf("创建生产者线程失败!");exit(EXIT_FAILURE);}}for (i = 0; i < consnum; ++i) {consarg[i] = i + 1;ret = pthread_create(&consid[i], NULL, consumerthread,(void *)&consarg[i]);printf("生产者consid[%d] = %lu\n", i + 1, consid[i]);if (ret != 0) {printf("创建消费者线程失败!");exit(EXIT_FAILURE);}}sleep(10);return 0;
}

22)利用匿名管道实现父子进程间通信,要求父进程发送字符串“hello child”给子进程;子进程收到父进程发送的数据后,给父进程回复“hello farther”;父子进程通信完毕,父进程依次打印子进程的退出状态以及子进程的pid

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>int main() {int fd1[2],fd2[2];pipe(fd1);pipe(fd2);int pid;pid = fork();if(pid < 0)perror("fork");else if(pid == 0) {close(fd1[0]);close(fd2[1]);char str[12];printf("This is the child!\n");if(read(fd2[0],str,12) > 0) {printf("Received the news: %s\n",str);if(write(fd1[1],"hello father",12) < 0)perror("write");} elseperror("read");exit(5);} else {int status;printf("This is the father!\n");close(fd1[1]);close(fd2[0]);char buf[24] = "hello child";if(write(fd2[1],buf,12) < 0)perror("write");else {printf("Send news successful!\n");}wait(&status);if(WIFEXITED(status)) {printf("The child's pid is: %d\n",pid);printf("The child's exited status is: %d\n",WEXITSTATUS(status));}}return 0;
}

23)利用匿名管道实现兄弟进程间通信,要求兄进程发送字符串“This is elder brother ,pid is (兄进程进程号)”给第进程;第进程收到兄进程发送的数据后,给兄进程回复“This is younger brother ,pid is(第进程进程号)”;

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
int main() {int fd1[2],fd2[2];pipe(fd1);pipe(fd2);int pid;pid = fork();if(pid == 0) {printf("This is the elder brother!\n");printf("The elder's father's pid is: %d\n",getppid());close(fd1[1]);close(fd2[0]);char str1[64],str2[64];sprintf(str1,"This is the elder brother,pid is %d",getpid());if(write(fd2[1],str1,64) < 0)perror("write");if(read(fd1[0],str2,64) < 0)perror("read");elseprintf("The news from younger is: %s\n",str2);} else {if(fork() == 0) {printf("This is the younger brother!\n");printf("The younger's father's pid is: %d\n",getppid());close(fd1[0]);close(fd2[1]);char buf1[64],buf2[64];if(read(fd2[0],buf1,64) > 0) {printf("The news form elder is: %s\n",buf1);sprintf(buf2,"This is the younger brother,pid is %d",getpid());if(write(fd1[1],buf2,64) < 0)perror("write");} elseperror("read");}}return 0;
}

24)利用有名管道文件实现进程间通信,要求写进程向有名管道文件写入10次“hello world”;读进程读取有名管道文件中的内容,并依次打印。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main() {int pid,fd;if(mkfifo("fifotest",0666) < 0)perror("mkfifo");pid = fork();if(pid < 0)perror("fork");else if(pid == 0) {printf("This is the write process!\n");int fd = open("fifotest",0666);for(int i = 0; i < 10; i++) {if(write(fd,"hello world",12) < 0)perror("write");sleep(1);}close(fd);} else {char str[128];printf("This is the read process!\n");int fd1 = open("fifotest",0666);for(int i = 0; i < 10; i++) {if(read(fd1,str,128) < 0)perror("read");elseprintf("%s\n",str);}system("rm -f fifotest");}return 0;
}

25)进程A向进程B发送SIGUSR1信号;进程B收到信号后,打印字符串“receive SIGUSR1”;要求用kill函数和signal函数实现以上功能;

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
#include<sys/types.h>void fun(int sig)
{if(sig=SIGUSR1){printf("Received SIGUSR1!\n");}
}int main(){printf("This is A process,mypid is:%d\n",getpid());signal(SIGUSR1,fun);pause();return 0;}

第三步:处理结果

因为程序中有pause()语句,那么程序运行到此就会停下知道有信号发送给此进程。
然后新建一个终端,在终端输入kill -SIGUSR 3701,那么第二个进程就会发送SIGUSR1信号给pid为3701的进程,也就是进程A。之后程序输出字符串,进程结束。
在这里插入图片描述

在这里插入图片描述
编写killend.c文件

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
void fun(int sig) {if(sig == SIGUSR1)printf("Reseived SIGUSR1!\n");
}
int main() {int pid;if(signal(SIGUSR1,fun) < 0)perror("signal");pid = fork();if(pid < 0)perror("fork");else if(pid == 0) {printf("This is B process!\n");sleep(2);} else {printf("This is A process!\n");if(kill(pid,SIGUSR1) < 0)perror("kill");return 0;}
}

26)调用setitimer函数分别触发SIGALRM信号,SIGVTALRM信号,SIGPROF信号 ;(可以由多进程分别触发每个信号)编写信号安装函数,在该函数内部能判断接受到的是什么信号,并把信号打印出来。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
void fun(int sig) {if(sig == SIGALRM)printf("Received the SIGALRM!\n");else if(sig == SIGVTALRM)printf("Receive the SIGVTALRM!\n");else if(sig == SIGPROF)printf("Receive the SIGPROf!\n");
}int main() {if(signal(SIGALRM,fun) < 0)perror("signal");if(signal(SIGVTALRM,fun) < 0)perror("signal");if(signal(SIGPROF,fun) < 0)perror("signal");struct itimerval new_value1,new_value2,new_value3;new_value1.it_value.tv_sec = 1;new_value1.it_value.tv_usec = 0;new_value1.it_interval.tv_sec = 2;new_value1.it_interval.tv_usec = 0;setitimer(ITIMER_REAL,&new_value1,NULL);new_value2.it_value.tv_sec = 1;new_value2.it_value.tv_usec = 0;new_value2.it_interval.tv_sec = 2;new_value2.it_interval.tv_usec = 0;setitimer(ITIMER_VIRTUAL,&new_value2,NULL);new_value3.it_value.tv_sec = 1;new_value3.it_value.tv_usec = 0;new_value3.it_interval.tv_sec = 2;new_value3.it_interval.tv_usec = 0;setitimer(ITIMER_PROF,&new_value3,NULL);while(1);return 0;
}

27)进程A向进程B发送SIGUSR1信号;进程B收到信号后,打印字符串“receive SIGUSR1”;要求用sigqueue函数和sigaction函数实现以上功能;

创建send_signal.c 文件

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <errno.h>int main() {int pid;printf ("请输入你将要发送给信号的进程的进程号:");scanf ("%d",&pid);            //输入接收信号的进程号union sigval mysigval;mysigval.sival_int = 20;if (sigqueue(pid,SIGUSR1,mysigval) == -1)    //向该进程发送信号,并且携带一个整数,这个整数会放在第二个参数中,一起发送给接受信号的进程perror("sigqueue error");elseprintf ("send ok \n");return 0;
}

创建receive_signal.c文件

#include<stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>int main() {int pid;printf ("pid is : %d \n",getpid());void myFun(int sig);struct sigaction act,oldact;act.sa_handler = myFun;        //定义接受信号的处理函数sigemptyset(&act.sa_mask);act.sa_flags = 0;if (sigaction(SIGUSR1,&act,&oldact) == -1)     //信号接收perror("sigaction: \n");pause();return 0;
}void myFun(int sig) {printf("I got a signal:%d\n",sig);printf ("receive SIGUSR1 \n");}

28)进程A向进程B发送信号,该信号的附带信息为一个值为20的整数;进程B完成接收信号的功能,并且打印出信号名称以及随着信号一起发送过来的整形变量值。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void handler(int sig,siginfo_t* info,void *p) {printf("The num is: %d\n",info->si_value.sival_int);
}int main() {int pid;struct sigaction act;act.sa_sigaction = handler;act.sa_flags = SA_SIGINFO;pid = fork();if(pid < 0)perror("fork");else if(pid == 0) {printf("This is the receive process!\n");if(sigaction(SIGUSR1,&act,NULL) < 0)perror("sigaction");while(1);} else {printf("This is the send process!\n");union sigval mysigval;mysigval.sival_int = 20;sleep(1);if(sigqueue(pid,SIGUSR1,mysigval) < 0)perror("sigqueue");}return 0;
}

29)创建共享内存,写进程通过键盘不断向内存写入“hello world”;如果结束写操作,则通过键盘输入“end”;读进程从共享内存读取数据,并打印。直到读到“end”为止。

创建shmread.c文件

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/shm.h>
#define MAXSIZE 1024struct shm{int write;    //记录读进程是否已经将内容读取char buffer[MAXSIZE];
};int main()
{int shmid;struct shm *share;void *shmptr = NULL;if(shmid = shmget(0X44,MAXSIZE,0666|IPC_CREAT) < 0)perror("shmget");if((shmptr = shmat(shmid,0,0)) == (void *)-1)perror("shmat");printf("This is the read process!!!\n");share = (struct shm *)shmptr;while(1){if(share->write != 0){if(!strncmp(share->buffer,"end",3) == 0){printf("%s",share->buffer);share->write = 0;}elsebreak;}}if(shmdt(shmptr) < 0)perror("shmdt");exit(0);
}

创建shmwrite.c文件

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/shm.h>
#define MAXSIZE 1024
struct shm {int write;        //记录读进程是否已经将内容读取char buffer[MAXSIZE];
};int main() {int shmid;void *shmptr = NULL;char str[MAXSIZE];    //存储输入的内容struct shm *share;if(shmid = shmget(0X44,MAXSIZE,0666|IPC_CREAT) < 0)perror("shmget");if((shmptr = shmat(shmid,0,0)) == (void *)-1)perror("shmat");printf("This is the write process!!!\n");share = (struct shm *)shmptr;while(1) {if(share->write == 1) {sleep(1);printf("Waiting the read process!!!\n");}printf("please input hello world!!!\n");fgets(str,MAXSIZE,stdin);sprintf(share->buffer,"%s",str);share->write = 1;if(strncmp(str,"end",3) == 0)break;sleep(1);}if(shmdt(shmptr) < 0)perror("shmdt");exit(0);return 0;
}

30)进程A向消息队列发送消息“hello,world”,进程B从消息队列读取消息,并打印。进程C向消息队列发送“自己在姓名”,进程D从消息队列中取出姓名字符串,并打印

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/msg.h>
#include <sys/types.h>
struct msg {char msg_str[128];
};int main() {int qid;struct msg mymsg;if(qid = msgget(0x66,0666|IPC_CREAT) < 0)perror("msgget");int pid;pid = fork();if(pid < 0)perror("fork");else if(pid == 0) {printf("This is A process!\n");sprintf(mymsg.msg_str,"hello world");if(msgsnd(qid,&mymsg,128,0) < 0)perror("msgsnd");} else {if(fork() == 0) {printf("This is B process!\n");if(msgrcv(qid,&mymsg,128,0,0) < 0)perror("msgrcv");printf("The msg is: %s\n",mymsg.msg_str);} else if(fork() == 0) {printf("This is the C process!\n");sprintf(mymsg.msg_str,"someonename");if(msgsnd(qid,&mymsg,128,0) < 0)perror("msgsnd");} else {printf("This is D process!\n");if(msgrcv(qid,&mymsg,128,0,0) < 0)perror("msgrcv");printf("The msg is: %s\n",mymsg.msg_str);}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/530987.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

登录界面验证码的实现

文章目录Javaweb实现验证码前端后台Springboot添加验证码项目结构依赖控制类前端页面效果图Javaweb实现验证码 前端 添加样式 <meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0, minimum-scale1.…

Javaweb MVC设计模式、Modle发展史、项目分层和三层架构

文章目录MVC设计模式MVC的目的MVC举例jspservletjavabean模式MVC的优点MVC的缺点Modle 发展史项目分层三层架构MVC设计模式 MVC模式&#xff08;Model-View-Controller&#xff09;是软件工程中的一种软件架构模式&#xff0c;把软件系统分为三个基本部分&#xff1a;模型&…

HTML表格和HTML表单

HTML 表格 表格由 <table> 标签来定义每个表格均有若干行&#xff08;由 <tr> 标签定义&#xff09;&#xff0c;每行被分割为若干单元格&#xff08;由 <td> 标签定义&#xff09; 字母 td 指表格数据&#xff08;table data&#xff09;&#xff0c;即数据…

解决虚拟机没有ens33网卡的问题

话不多说&#xff0c;直接操作 解决办法 1.在终端中输入: sudo vim /etc/network/interfaces进入interfaces文件后&#xff0c;然后输入以下代码&#xff0c;然后保存退出 auto ens33 iface ens33 inet dhcp 2.重启虚拟机 输入ifconfig命令&#xff0c;成功启动ens33网卡

HDFS上传文件命令报错org.apache.hadoop.ipc.RemoteException(java.io.IOException)

作为作者&#xff0c;强烈不建议进行格式化hadoop&#xff0c;毕竟开发数据是最为重要的&#xff01; Hadoop 3.1 hdfs dfs -put /源文件路径 /目的文件路径解决方案 第一步&#xff1a;停止主节点&#xff08;Master&#xff09;和子节点服务&#xff08;Slave&#xff09; …

图(Graph)的学习

文章目录图的认识图的概念无向图有向图简单图完全图子图连通、连通图、连通分量边的权和网加权图邻接和关联路径简单路径、简单回路环顶点的度、入度和出度割点&#xff08;关节点&#xff09;桥(割边)距离有向树图的表示邻接列表邻接矩阵图的遍历深度优先遍历广度优先遍历生成…

并查集(Disjiont Set)

并查集 并查集的最大作用是检测一个图上面存不存在环。 无向图&#xff0c;六个顶点 显然 1-2-4-3连成一个环 #include<stdio.h> #include<stdlib.h>#define VERTICES 6void initialise(int parent[]){int i;for(i0;i<VERTICES;i){parent[i]-1; }}int find_…

采用Kruskal算法生成最小生成树,并采用并查集的合并优化和查询优化。

文章目录最小生成树1.什么是图的最小生成树&#xff08;MST&#xff09;?2.最小生成树用来解决什么问题&#xff1f;Kruskal&#xff08;克鲁斯卡尔&#xff09;算法算法描述图解最小生成树 1.什么是图的最小生成树&#xff08;MST&#xff09;? 用N-1条边连接N个点&#x…

Java连接Mysql数据库(JDBC)

文章目录导入包con、stmt、rs 三者存在一定的关系getInt和getStringinput.nextInt();简单使用讲解ResultSet和StatementPreparedStatement的用法JDBC连接代码更多样例导入包 import java.sql.Connection; import java.sql.DriverManager; import java.sql.statement; import j…

Linux编程考前测试题

文章目录选择题多选题判断题填空题简答题编程题选择题 1:当打开vi文本编辑器编辑文件时&#xff0c;vi处于&#xff08;A&#xff09;模式 A: 命令模式 B: 编辑模式 C: 实模式 D: 虚模式 2:下列有关fork&#xff08;&#xff09;函数返回值说法错误的是&#xff08;D&#xf…

MySQL考试复习(知识点、练习题)

文章目录数据库的管理技术的三个阶段发展的三个阶段数据库的锁数据库设计的基本步骤事务的四大特性什么是视图如果关系模式设计不好&#xff0c;可能带来哪几个问题数据库管理系统的主要功能有哪些数据库系统中的常见故障有哪些简述SQL语言的组成说明关系模型有哪三类完整性规则…

Oracle复习(知识点、练习题、实验)

文章目录第一章 数据库概念数据库的三级模式结构&#xff1a;模式、外模式、内模式三级模式之间的映射第二章 Oracle12g体系结构Oracle的逻辑存储结构Oracle物理存储结构Oracle11g服务器结构系统全局区&#xff08;SGA&#xff09;程序全局区&#xff08;PGA&#xff09;第三章…

Openstack面试题和知识点总结

文章目录知识点云计算起源定义特点分类服务类型平台分类应用虚拟化虚拟化技术定义分类云计算和虚拟化的关系虚拟化的优点OpenStack简介核心架构Openstack组件共享服务组件核心组件组件详解RabbitMQ概念特点rabbitmq中的概念工作原理常用操作MemcachedKeystoneGlance工作原理Nov…

auto.js 实现信息发送、QQ点赞、微信点赞、健康日报签到

文章目录auto.js开发文档安装total control在手机端安装auto.js apk安装vscode短信多条发送QQ点赞微信点赞健康日报填写叠猫猫auto.js开发文档 点击学习 安装total control total control 用于手机投屏在电脑屏幕上 在手机端安装auto.js apk 链接&#xff1a;https://pan.…

MapReduce综合学习含Wordcount案例

文章目录MapReduce简介MapTaskReduceTaskMapper阶段解读Reducer阶段解读MapReduce适用的问题MapReduce的特点MapReduce基本思想大数据处理思想&#xff1a;分而治之构建抽象模型&#xff1a;Map 函数和 Reduce 函数上升到架构&#xff1a;并行自动化并隐藏底层细节MapReduce计算…

基于Spring boot+Vue的在线考试系统

文章目录spring boot 分层图解安装idea配置阿里云镜像项目启动前端项目结构项目前端中index.htmlApp.vuemain.jsrouter整个页面渲染过程关于矢量图图标的使用引入JQuery依赖github-markdown-css样式文件-一般用作文章正文的样式美化spring boot 分层图解 安装idea 安装参考 id…

Java基础总结之(面试)

文章目录Java标识符Java修饰符访问权限修饰符访问控制和继承非访问权限修饰符局部变量修饰符接口接口中方法修饰符运算符算术运算符一元运算符二元运算符算术赋值运算符赋值运算符逻辑运算符&#xff08;&&、||和!&#xff09;关系运算符自增和自减运算符&#xff08;和…

Javaweb练手项目

文章目录学生管理系统音乐网站锋芒博客中医药管理系统博客天梯CMS系统锋芒社团官网学生管理系统 实现技术&#xff1a;ServletMVC&#xff08;模式&#xff09;Filter(过滤器&#xff09;html 主要功能&#xff1a;学生信息的增删查改&#xff0c;文件&#xff08;图片&#x…

Spark之scala学习(基础篇)待更新

文章目录引言大数据介绍大数据与云计算区别大数据和人工智能的区别大数据和传统的分析&#xff08;excel&#xff09;的区别scala的特性面向对象特性函数式编程函数式编程的特点&#xff1a;函数式编程的优势静态类型扩展性并发性为什么要学scalascala安装简单测试了解ScalaSca…