1、学会通过基本的linux进程控制函数,由父进程创建子进程,并实现协同工作
2、创建两个进程,让子进程读取一个文件,父进程等待子进程读完文件后继续执行
注意:
fork创建的新进程被称为子进程,该函数被调用一次,但返回两次。两次返回的区别是:在子进程中的返回值是0,而在父进程中的返回值则是新进程的进程ID。
创建子进程,父进程哪个先运行根据系统调度且赋值父进程的内存空间。
vfork创建子进程,但子进程先运行且不复制父进程的内存空间
#include
#include
#include
#include
#include int main(void){printf("pid:%d\n",getpid());pid_t pid;pid = fork(); // 创建子进程// 在fork之后会运行两个进程(父进程、子进程)if(pid <0){perror("fork error");} else if(pid>0){// 父进程(在父进程中fork返回的是子进程的pid)printf("I am parent process pid is %d,ppid is %d,fork return is %d\n",getpid(),getppid(),pid);} else { // 子进程(在子进程中fork返回的是0) printf("I am child process pid is %d,ppid is %d,fork return is %d\n",getpid(),getppid(),pid); }printf("pid:%d\n",getpid());sleep(1); // 睡眠return 0;
}
编译源文件:
root@ubuntu:/home/course/linux# gcc -o /home/course/linux/out/createThread /home/course/linux/createThread.c
-c
表示只编译(compile)源文件但不链接,会把.c或.cc的c源程序编译成目标文件,一般是.o文件。-o
用于指定输出(out)文件名。不用-o的话,一般会在当前文件夹下生成默认的a.out文件作为可执行程序。root@ubuntu:/home/course/linux/# out/createThread # 直接运行
可以看到:
父进程(在父进程中fork返回的是子进程的pid)
子进程(在子进程中fork返回的是0)
返回顶部
使用sleep()函数,实现线程的睡眠,每个进程运行后休眠一段时间,这时按照cpu的资源调度,使得其他进程运行。(若休眠时间短则会出现二次调用的情况)
#include
#include
#include
#include
#include int main(void){printf("pid:%d\n",getpid());pid_t pid;pid = fork(); // 创建子进程// 在fork之后会运行两个进程(父进程、子进程)if(pid <0){perror("fork error");} else if(pid>0){for(int i=0;i<10;i++){// 父进程(在父进程中fork返回的是子进程的pid)printf("I am parent process pid is %d\n",getpid());sleep(1);}} else { for(int i=0;i<10;i++){// 子进程(在子进程中fork返回的是0) printf("I am child process pid is %d\n",getpid()); sleep(1);}}return 0;
}
编译运行:
root@ubuntu:/home/course/linux# vi createThread1.c
root@ubuntu:/home/course/linux# gcc -o /home/course/linux/out/createThread1 /home/course/linux/createThread1.c
返回顶部
父进程使用两种IO的形式进行文件的写入,默认当前路径下创建文件。注意区分缓存的概念以及文件的内容输出。
#include
#include
#include
#include
#include int main(void){printf("pid:%d\n",getpid());/*父进程调用写文件*/FILE *fp =fopen("s.txt","w");int fd = open("s_fd.txt",O_WRONLY|O_CREAT|O_TRUNC,S_IRWXU|S_IRWXG);char *s = "hello world!";ssize_t size = strlen(s)*sizeof(char);// 标准IO函数 - 带缓存 - 全缓存fprintf(fp,"s:%s,pid:%d",s,getpid());// 内核提供的IO系统 - 不带缓存write(fd,s,size);pid_t pid;pid = fork(); // 创建子进程// 在fork之后会运行两个进程(父进程、子进程)if(pid <0){perror("fork error");} else if(pid>0){for(int i=0;i<10;i++){// 父进程(在父进程中fork返回的是子进程的pid)printf("I am parent process pid is %d\n",getpid());sleep(1);}} else { for(int i=0;i<10;i++){// 子进程(在子进程中fork返回的是0) printf("I am child process pid is %d\n",getpid()); sleep(1);}}// 父子进程都要执行 - 写入各自缓存fprintf(fp,"pid:%d",getpid());return 0;
}
可以看到编译正常运行;
并且在目录下新生成了 s_fd.txt、s.txt 文件,当我们查看文件内容的时候,会发现两个文件中的内容有偏差:
使用内核提供的IO系统 - 不带缓存,是直接将内容写入,而标准IO函数 - 带缓存,写的内容是:fprintf(fp,"s:%s,pid:%d",s,getpid());
,并且在最后的时候父子进程都要执行一次标准的IO,將各自的缓存内容写入到文件中去,所以会重复内容一次。
返回顶部
实验说明:
解决方案:
#include
#include
#include
#include
#include
#include
#include#define COLMAX 1024 //每一个字符串的最大长度(列)
#define ROWMAX 64 //字符串最大个数(行)/*
本代码实现用子进程打开同目录下的s_fd.txt文件
并且父进程输出内容
*/int main(void) {int p_id = -1;//子进程创建失败if ((p_id = fork()) == -1) {printf("Process_1 Create Error\n");} else if (p_id == 0) { //子进程部分printf("%d Process Start Work\n", getpid());char text[ROWMAX][COLMAX] = {0};FILE *fp = fopen("s_fd.txt", "r+");//打开文件if (fp == NULL) { //打开文件失败printf("Fail to open file!\n");} else {int i = 0;while ((fscanf(fp, "%s", text[i])) != EOF) {printf("%s\n", text[i]);i++;sleep(1); //等待1s方便查看输出}}fclose(fp);exit(0);}//父进程部分waitpid(p_id, NULL, 0);//阻塞等待printf("%d process is end\n", p_id);return 0;
}
rse/linux# vi createThread3.c
root@ubuntu:/home/course/linux# gcc -o /home/course/linux/out/createThread3 /home/course/linux/createThread3.c
root@ubuntu:/home/course/linux# out/createThread3
运行结果:
返回顶部
实验说明:
解决方案:
#include
#include
#include
#include
#include
#include
#includestatic int sharedata=4; // 共享数据void *create(void *arg){printf("new pthread...\n");printf("sharedata data = %d \n",sharedata);sharedata = 3;return (void *)(0);
}int main(void){pthread_t mythread ;sharedata=5; // 修改变量值int error = 0;error = pthread_create(&mythread,NULL,create,NULL);if(error){printf("pthread_create is not created...\n");return -1;}sleep(1);printf("pthread_create is ok...\n");printf("And shared data = %d\n \n",sharedata);return 0;
}
root@ubuntu:/home/course/linux# vi createThread4.c
root@ubuntu:/home/course/linux# gcc -o /home/course/linux/out/createThread4 /home/course/linux/createThread4.c -l pthread
root@ubuntu:/home/course/linux# out/createThread4
运行结果:
如有报错,参见:https://blog.csdn.net/u014470361/article/details/83214911
返回顶部
实验说明:
解决方案:
区分单词原则:
#include
#include
#include
#include
#include pthread_mutex_t counter_clock=PTHREAD_MUTEX_INITIALIZER;int main(int ac,char *av[]){void *count_words(void *);if(ac!=3){printf("Usage:%s file1 file2\n",av[0]);exit(1);}/*分別以av[1]、av[2]作为参数,创建两个线程t1、t2,线程t1、t2进入等待状态,输出统计的单词总数*/pthread_t tidp1,tidp2;int error1,error2;error1=pthread_create(&tidp1,NULL,count_words,av[1]);error2=pthread_create(&tidp2,NULL,count_words,av[2]);pthread_join(tidp1,NULL);pthread_join(tidp2,NULL);return 0;
}void *count_words(void *f){char *filename=(char *)f;FILE *fp;int c,prevc='\0';int total_words=0;if((fp=fopen(filename,"r"))!=NULL){while((c=getc(fp))!=EOF){if(!isalnum(c) && isalnum(prevc)){pthread_mutex_lock(&counter_clock);total_words++;pthread_mutex_unlock(&counter_clock);} prevc=c;}fclose(fp);printf("total_words=%d\n",total_words);}else{perror(filename);}return NULL;
}
创建两个包含英文单词的txt
文件:
root@ubuntu:/home/course/linux# vi createThread5.c
root@ubuntu:/home/course/linux# gcc -o /home/course/linux/out/createThread5 /home/course/linux/createThread5.c -l pthread
root@ubuntu:/home/course/linux# ./out/createThread5 ./a.txt ./b.txt
total_words=5
total_words=3
运行结果:
返回顶部
上一篇: 表扬信高考优秀范文【优质6篇】
下一篇: 如果还有明天高三作文【精简3篇】