介绍了Linux下fork()创建进程以及使用pthread_create()创建线程的方法

1. 基于进程的斐波那契数列

在下面的代码中,由子进程进行斐波那契数列的输出,父进程要等待子进程输出完毕,然后再执行。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> int main(int argc, char* argv[])
{
/**
* pid用来保存fork()的返回值
* n用来保存用户输入
* f0,f1,f2用于计算斐波那契数列
*/
pid_t pid;
int i;
int n;
int f0, f1, f2;
f0 = 0;
f1 = 1; /**
* 命令行参数验证
* argv[1]表示用户输入的命令行参数,这里是5
* 如果用户没有输入这个参数,提示用户不能为空,然后返回
* 如果用户输入的是负数,提示用户要输入一个正数,然后返回
* atoi()是把字符串转换为整数的方法
*/
if (argv[1] == NULL)
{
fprintf(stderr, "命令行参数不能为空\n");
exit(-1);
} if (atoi(argv[1]) < 0)
{
fprintf(stderr, "请输入一个正数\n");
exit(-1);
} /**
* 用fork()来创建新进程,
* 返回值如果<0,表示进程创建失败,
* 如果=0,表示该进程是一个子进程,
* 否则,表示该进程是父进程
*/
pid = fork(); //进程创建失败的情况,此时提示fork失败
if (pid < 0)
{
fprintf(stderr, "fork failed");
exit(-1);
} else if (pid == 0)
//pid = 0表示子进程,在子进程中要完成斐波那契数列的计算输出
{
n = atoi(argv[1]);
printf("参数为:%d\n", n);
if (n == 1) {
printf("%d ", f0);
} else {
printf("%d %d ", f0, f1);
for (i = 3; i <= n; i++) {
f2 = f0 + f1;
f0 = f1;
f1 = f2;
printf("%d ", f2);
}
}
printf("\n子进程执行完毕\n");
} else {
//此时表示父进程,父进程要先等待(wait)子进程执行完毕,然后再执行
wait(NULL);
printf("父进程执行完毕\n");
} return 0;
}

2. 基于线程的斐波那契数列

在下面代码中,由子线程负责斐波那契数列的数据保存,父线程需要等待子线程的数据全部保存完毕,才能输出数据。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h> /**
* 该函数是一个子线程函数,在这里给斐波那契数列的数组fib赋值
* 即在子线程中把数据算好,保存在数组fib当中
* 由于子线程和父线程可以共享数据,所以fib在子线程结束以后还存在
*/
void *thread_fun(int *fib)
{
int i;
int num = fib[0];
fib[1] = 0;
fib[2] = 1; for (i = 3; i <= num; i++) {
fib[i] = fib[i-1] + fib[i-2];
} return NULL;
} int main(int argc, char* argv[])
{
/**
* ntid用来保存子线程的线程指针
* err用来保存pthread_create的返回值
* 定义了一个数组fib[50]用来存储斐波那契数列的数据
* 用n来接受用户输入
*/
pthread_t ntid;
int err;
int i;
int n;
int fib[50]; /**
* 命令行参数验证
* argv[1]表示用户输入的命令行参数,这里是5
* 如果用户没有输入这个参数,提示用户不能为空,然后返回
* 如果用户输入的是负数,提示用户要输入一个正数,然后返回
* atoi()是把字符串转换为整数的方法
*/
if (argv[1] == NULL)
{
fprintf(stderr, "命令行参数不能为空\n");
exit(-1);
}
if (atoi(argv[1]) < 0)
{
fprintf(stderr, "请输入一个正数\n");
exit(-1);
} /**
* n来接收用户的输入
* 用fib[0]来保存用户输入的数据,以方便下一步传参数
*/
n = atoi(argv[1]);
fib[0] = n; /**
* 创建一个新的线程,第一个参数用来保存线程的指针,第二个参数设置为NULL
* 第三个参数表示子线程要执行的函数,第四个参数为函数的参数
* 我们把fib这个数组传过去
*/
err = pthread_create(&ntid, NULL, thread_fun, (void *)fib); //err!=0表示线程创建失败的情况,此时提示错误
if (err != 0) {
fprintf(stderr, "线程创建失败\n");
exit(-1);
}
//如果执行到这里,表示子线程创建成功,但是父线程需要等待子线程执行完毕
//pthread_join()方法表示父线程要等待子线程ntid的执行,ntid是刚才创建线程时保存子线程的指针
pthread_join(ntid,NULL); /**
* 到这里表示子线程已经执行完毕了,所有数据应该都有了
* 那么我们可以将他们打印出来了
*/
printf("子线程执行完毕,由父线程输出数据:\n");
for(i = 1; i<= n; i++) {
printf("%d ", fib[i]);
} printf("\n");
}

最新文章

  1. react.js
  2. CSS中的display属性
  3. iOS开发——UI基础-屏幕适配
  4. PHP环境下Memcache的使用方法
  5. 0040 Linux 系统管理命令
  6. 正则表达式_删除字符串中的任意空格(Regex)
  7. 【30】透彻了解inlining 的里里外外
  8. Linux操作系统的LILO详解
  9. 《Effective C++》条款26 防卫潜伏的ambiguity模棱两可的状态
  10. ADO.NET—两种连接模式
  11. FasfDFS整合Java实现文件上传下载
  12. 【js】前端 js/jquery 常用代码和实践
  13. [Swift]LeetCode213. 打家劫舍 II | House Robber II
  14. 五一劳动节,讲讲NEO智能合约的调试
  15. 隐藏input光标和输入内容方法
  16. 一款优秀的前端框架——AngularJS
  17. ava 8中的新功能特性
  18. Ext.js入门:Window对象与FormPanel(六)
  19. How to Catch Ctrl-C in Shell Script
  20. linux常用命令及系统常见符号

热门文章

  1. Axure-计算输入字数
  2. Python 中print 和return 的区别
  3. dns2tcp使用教程
  4. chrome 打开上次关闭的tab ctrl+shift+T
  5. 数组、list排序
  6. jquery点击tr换背景颜色
  7. ios之AFN
  8. ios 封装sqllite3接口
  9. 【简●解】[AHOI2009]中国象棋
  10. c++的if语句中的110为什么不等于110?