介绍了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");
}

Linux中的进程与线程的更多相关文章

  1. linux中的进程和线程

    应用程序:可以被操作系统执行的一组指令和参数的集合,是静态的,并存储在磁盘空间中: 进程:在操作系统中在运行程序后,处于运行状态的程序,是应用程序的一个执行过程,同时也是操作系统分配内存,cpu等系统 ...

  2. Java中的进程与线程(总结篇)

    详细文档: Java中的进程与线程.rar 474KB 1/7/2017 6:21:15 PM 概述: 几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进 ...

  3. liunx中的进程与线程

    1. 进程和线程 进程和线程是程序运行时状态,是动态变化的,进程和线程的管理操作(比如,创建,销毁等)都是有内核来实现的. Linux中的进程于Windows相比是很轻量级的,而且不严格区分进程和线程 ...

  4. Linux中查看进程的多线程pstree, ps -L

    Linux中查看进程的多线程 在SMP系统中,我们的应用程序经常使用多线程的技术,那么在Linux中如何查看某个进程的多个线程呢? 本文介绍3种命令来查看Linux系统中的线程(LWP)的情况:在我的 ...

  5. Linux下的进程与线程(二)—— 信号

    Linux进程之间的通信: 本文主要讨论信号问题. 在Linux下的进程与线程(一)中提到,调度器可以用中断的方式调度进程. 然而,进程是怎么知道自己需要被调度了呢?是内核通过向进程发送信号,进程才得 ...

  6. windows中的进程和线程

    今天咱们就聊聊windows中的进程和线程 2016-09-30 在讨论windows下的进程和线程时,我们先回顾下通用操作系统的进程和线程.之所以称之为通用是因为一贯的本科或者其他教材都是这么说的: ...

  7. Java中的进程和线程

     Java中的进程与线程 一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是 ...

  8. python中的进程、线程(threading、multiprocessing、Queue、subprocess)

    Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然.你做到了你就比别人NB. 我们先了解一下什么是进程和线程. 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CP ...

  9. 如何在 Linux 中查看进程占用的端口号【转】

    对于 Linux 系统管理员来说,清楚某个服务是否正确地绑定或监听某个端口,是至关重要的.如果你需要处理端口相关的问题,这篇文章可能会对你有用. 端口是 Linux 系统上特定进程之间逻辑连接的标识, ...

随机推荐

  1. 新建cordova应用,插件开发教程系列(总目录)

    以下几篇是连续的教程,代码也是连续的,包括如下章节: 新建cordova应用 https://www.cnblogs.com/cannel/p/11074359.html 使用cordova把h5应用 ...

  2. 在自己的工程中使用ijkplayer的功能

    最近在做一个软解视频叠加硬解视频的方案,网上看了很多教程,始终不得要领.虽然ijkplayer提供了ijkplayer-example这个示例工程,但对于初入安卓的人来说,要将ijkplayer整合到 ...

  3. 磁盘格式化mke2fs

    -b 设置每个块的大小,当前支持1024,2048,40963种字节 -i 给一个inode多少容量 -c 检查磁盘错误,仅执行一次-c时候,会进行快速读取测试:-c -c会测试读写,会很慢 -L 后 ...

  4. pip和pip3安装、升级、版本查看及遇到的问题

    pip的安装 问题一 sudo apt-get install python-pip #安装pip sudo pip install --upgrade pip -i http://mirrors.a ...

  5. dockerfile 的最佳实践

    Dockerfile 编写nginx容器 [root@mast nginx]# cat Dockerfile FROM centos MAINTAINER zhaoruidong RUN yum -y ...

  6. django 模板中{%for%}的使用

    1.{%for athlete in list reversed%}  reversed用于反向迭代 2.for 标签 支持一个可选的 empty 变量 3.forloop 模板变量 4.forloo ...

  7. 1.入手树莓派之linux环境搭建

    最近刚刚买了一款 树莓派3代B型 raspberrypi 板载蓝牙和WIFI 英国版本,没玩过,觉得很好奇,生怕记性不好哈,把自己玩的过程记录一下,以备不时之需: 需要材料: 1) 树莓派: 2)sd ...

  8. python之bool (布尔值)

    用途: ​ 判断真假 识记: 空的字符串是False,非空的就是True 0 是False,非0的都是True 格式: True False 布尔值转换成字符串: print(type(str(Tru ...

  9. luogu P1205 方块转换

    题目描述 一块N x N(1<=N<=10)正方形的黑白瓦片的图案要被转换成新的正方形图案.写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式: 1:转90度:图案按顺时针 ...

  10. INFORMATION_SCHEMA InnoDB 表

    INFORMATION_SCHEMA InnoDB Tables 本节提供InnoDB INFORMATION_SCHEMA表的表定义. 有关相关信息和示例,请参见"InnoDB INFOR ...