日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux高级编程实验(30个)

發布時間:2025/3/8 linux 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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; }

總結

以上是生活随笔為你收集整理的Linux高级编程实验(30个)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 五月天综合色 | 久久av网 | 影音先锋成人资源网站 | 免费古装一级淫片潘金莲 | 性xxxx视频播放免费 | 日本少妇激情舌吻 | 香蕉茄子视频 | 全黄一级男人和女人 | 天天干夜夜欢 | 国产依人 | 一级黄色大片视频 | 最近免费中文字幕大全免费版视频 | 亚洲第一成年网 | 国产一卡二卡三卡 | 特级一级黄色片 | 久久96| 美女下部无遮挡 | 99精品在线播放 | 一直草 | 欧美日韩高清在线观看 | 日韩欧美亚洲一区二区三区 | 爱情岛亚洲论坛入口 | 一级丰满大乳hd高清 | av网站在线免费观看 | 亚洲国产网| 澳门一级黄色片 | 欧美三级不卡 | 亚洲不卡在线视频 | 日韩免费一区二区三区 | 精品人妻无码一区二区三区蜜桃一 | 91精品国产视频 | 蜜臀一区二区三区精品免费视频 | 国产精品成人午夜视频 | 亚洲jizzjizz日本少妇 | 国产在线播放91 | 亚洲免费观看高清完整 | 欧美日韩精品久久久免费观看 | 久草手机在线视频 | 成人黄色短视频在线观看 | 精品区一区二区 | 艳妇臀荡乳欲伦交换在线看 | 明星双性精跪趴灌满h | 五月天丁香婷 | 福利小视频在线播放 | 国产又爽又黄又嫩又猛又粗 | 丝袜 亚洲 另类 欧美 重口 | 中文字幕精品在线 | 亚洲天天做 | 超碰一区二区 | 免费成人一级片 | 国产精品成人无码免费 | 天天天干干干 | 蜜桃视频一区二区 | 光棍影院手机版在线观看免费 | 91成人免费电影 | 在哪里可以看黄色片 | 无码少妇一区二区三区 | 欧美黄色录像视频 | 99久久精品国产一区色 | 黄色喷水视频 | 久热精品在线视频 | 日韩无码专区 | 国产精品不卡一区二区三区 | 色婷婷综合视频 | 人人做人人爱人人爽 | 日韩精选视频 | 怎么可能高潮了就结束漫画 | 亚洲一区二区三区人妻 | 欧洲中文字幕日韩精品成人 | 四虎网站 | 日韩精品一区二区三区网站 | 免费精品一区二区 | 玖玖爱av | 欧美黄色大片视频 | 国产一区二区三区免费视频 | 乳罩脱了喂男人吃奶视频 | 精品欧美黑人一区二区三区 | 黄色一级免费大片 | 亚洲va在线∨a天堂va欧美va | 欧美性高潮视频 | 成人午夜sm精品久久久久久久 | 精品午夜视频 | 一区二区三区爱爱 | 四虎成人免费视频 | 插骚 | 天天弄天天干 | 成人动漫av | 亚洲AV无码成人精品一区 | 中国一区二区三区 | sese综合| 伊人性视频 | 欧美精品小视频 | 国产福利免费视频 | 草草久久久 | va视频在线观看 | 美国免费黄色片 | gav久久| 小镇姑娘1979版 | 天天做夜夜爽 |