进程控制------基础、fork、exec、system

1、什么是进程?区分程序
进程是指程序执行的可执行文件;而程序是存放到磁盘的可执行文件;

2、进程的一些特性:
(1)动态性:进程的实质是程序的一次执行过程,进程是动态产生,动态消亡的
(2)并发性:任何进程都可以同其他进程一起并发执行
(3)独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位
(4)异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进
(5)结构特征:进程由程序、数据和进程控制块三部分组成.

3、进程互斥:
(1)、概念:进程互斥是指当有若干进程都要使用某一共享资源时,任何时候最多允许一个进程使用,其他要使用该资源的进程必须等待,直到占用该资源者释放了该资源为止。

(2)、例如:车站的买票窗口,假如现在总共有十张编号座位号的票,现在有两个窗口都开着一起 卖这十张票,此时编号为1 的票开始出票,两个窗口都在卖这张,编号1的就一张,他只允许被一个窗口售卖(被一个进程占用),这时候就产生了进程的互斥;

(3)、临界资源:这样的车票就被称为临界资源(操作系统中将一次只允许一个进程访问的资源称为临界资源)

(4)、临界区:进程中访问临界资源的那段程序代码称为临界区
还拿上面的卖票,我们知道的在实际卖票的过程中,同一张票不可能卖两次,具有唯一编号的票只能被买一次,这就是因为买票系统有自己的临界区,他里边有程序来保证每张票在同一时刻只会被一个窗口售卖(也就是纸杯一个进程占用);
抢锁、上锁—->取票——>票数减1—–>开锁;
也就是两个进程竞争抢占这个资源,抢到之后上锁,其他进程都是进不来,你在里边占用这个资源,也就是取票,占用结束之后,开锁,这时候想要抢占资源的进程又可以重新抢锁;这个过程编码实现后就是临界区

4、进程id:

每个进程都有一个ID(ID是一个正整数),唯一标识了系统中的这个进程。
每个进程都有一个创建它的进程,叫父进程(Parent Process);
进程ID(PID):标识进程的唯一数字;
父进程ID(PPID);
启动进程的用户ID(UID);

5、获取进程id的函数getpid:
(1)获取本进程ID
pid_t getpid(void)

(2)获取父进程ID
pid_t getppid(void)

(3)例子代码:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>


int main()
{
    printf ("当前进程 Id:  %d\n", getpid());
    printf ("当前父进程Id: %d\n", getppid());
    printf ("当前用户  Id: %d\n", getuid());

    while (1);

    return 0;
}

6、进程创建fork

(1)、当fork()顺利完成任务时,就会存在两个进程,每个进程都从fork()返回处开始继续执行。
(2)他俩只会共享代码段,子进程的数据段,堆,栈都是copy了一份父进程的,不共享;
(3)不能确定那一个进程先执行
(4)创建进程代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

 //pid_t fork(void);

int main()
{   
    pid_t pid = fork();  //如果你创建成功有两个返回值,一个0代表子进程返回值,一个大于0的数字,是父进程返回的子进程的id号;

    if(pid == -1)  //-1表示创建失败;
    {

        printf("创建子进程失败了\n");
    }
    else if(pid > 0)
    {
        printf("我是父亲进程: %d\n",getpid());
    }
    else (pid == 0)
    {
        printf("我是子进程:%d\n",getpid());
    }

    return 0;
}

(5)体现不共享数据段的代码:

int main()
{
    int count = 0;
    pid_t pid = fork();  
    //创建子进程后会有两个进程跑这段代码,会有两个打印,值都是1,说明两个进程跑的时候count初始值都是0;并没有共享数据段,一个程序跑完后加一,另一个程序接着在前一个程序的数据基础上再加一; 
    count++;
    Printf(“%d\n”,count);
    Return 0;
}

7、exec函数(execl,execlp,execv,sysytem)

(1)exec用被执行的程序替换调用它的程序
从替换调用他的程序代码这一方面来说下面三个是属于一类
Execl:int execl(const char * path, const char* arg1,…)
Execlp:int execlp(const char * path, const char* arg1,…)
Execv:int execv(const char path, const char argv[])//可执行程序存进字符串指针数组,和上面两个没有本质区别

Execl替换例子代码:

int main12()
{
    int ret = execl("/bin/ls", "ls"  ,NULL);//这个execl创建的新的进程替换了原有的代码段;ls是存在于linux中bin目录下的可执行文件,功能展示当前所在目录的文件;
    if (ret == -1)
    {

        return -1;
    }
    printf("aaaaaaaaaaaa\n");  //打印的这一段代码已经被替换,不会有输出;
    return 0;
}

(2)区别于fork:
fork 创建一个新的进程,产生一个新的PID
exec 启动一个新程序,替换原有的进程,因此进程的PID不会改变。
(3)System
格式:int system(const char* string)
这个好,这个不会替换调用他的函数的代码;调用fork产生子进程,由子进程来调用 /bin/sh -c string来执行参数string所代表的命令,这个调用起来真的是超级方便,不用像exec那么多的参数;
看代码:

int main7()
{
    printf("aaaaaaaaaaaaaaaaaa\n");
    system("clear");
    sleep(1);
    system("ls");
printf("aaaaaaaaaaaaaaaaaaccccccc\n");

return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值