【Linux之路】进程与线程(一)


1, Linux进程组成:

       1)进程控制块(PCB)  存放进程标志信息  现场信息  控制信息      是进程的标志(随进程的创建而创建,消亡而消亡)

       2)进程程序块                  存放进程执行的指令代码

       3)进程内核栈                  保存 中断/异常现场 以及 执行函数调用时存放参数和返回地址(这个有点像汇编里面的call ret?忘了 = =), 只当进程在内核态下工作才使用

       4)进程数据块                  存放私有数据,用户栈,线程只包含前三个

2, 创建进程:

       1)fork( )  创建新进程, 新进程完全复制父进程的资源(副本?)而且直到开始更改时才复制(效率问题), 执行上独立于父进程, 与父进程 通过pipe等方式通信

       2)vfork( ) 与fork( )相似, 不同的是,新进程不会重新复制父进程的资源, 而是共享父进程的资源。而且执行时会block父进程, 直到exec( )或exit( ). 相当于函数调用。。

       3)clone( ) 创建线程, 其使用为 clone( (void*)func, stack, clone_flag, arg); 返回值应该是线程的句柄, 其中:

func 为执行程序,函数名为void* func(int arg),
stack 为线程使用的内核栈, 经常是 stack = (char*)malloc(STACK_FRAME);  stack += STACK_FRAME;  请求内存空间
flags 可以是CLONE_VM, CLONE_FS, CLONE_FILE CLONE_SIGHAND 和CLONE_PID的组合(即 "|")
而arg 则应为func的参数

例子程序 vfork 与 fork函数的比较:

在这里说一下, 执行完fork后 会生成两个方向的程序(复制下方的程序代码组成的进程?),fork会返回两个值(成功创建的话), 一个给父进程(pid就是子进程的进程ID 正数), 一个给子进程(pid = 0),  如果失败的话, 返回-1

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

int main(void) 
{
  int data = 0;
  pid_t pid;
  int choose = 0;
  while ( (choose = getchar()) != 'q') {
    switch (choose) {
    case '1':
      pid = fork();
      if (pid < 0) {
        printf ("Error!\n");
      }
      if (pid == 0) {
        data++;
        exit(0);
      }
      wait(pid);
      if (pid > 0) {
        printf("data is %d\n", data);
      }
      break;
    
    case '2':
      pid = vfork();
      if (pid < 0) {
        printf ("Error!\n");
      }
      if (pid == 0) {
        data++;
        exit(0);
      }
      wait(pid);
      if (pid > 0) {
        printf("data is %d\n", data);
      }
      break;
    default:
      break;
    }
  }
}

执行结果为:

1
data is 0
2
data is 1
q

表明: vfork( ) 的内存空间与父进程共用, 而fork( ) 是“独立”的“新建”的内存空间(在需要修改的时候方创建副本, 效率问题, 总不能只需只读的情况下还要复制大量的数据吧)

    4)exec( ) 替换原来的新程序(代码段),废弃原有的数据段与堆栈段, 只使用进程号,可以用于vfork/ exec 创建新进程

#include <errno.h>
#include <error.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char command[256];

int main () 
{
  int rtn;
  bool flag = true;
  while (flag) {
    flag = false;
    printf(">");
    fgets( command, 256, stdin);
    command[strlen(command)-1] = 0;
    if ( fork() == 0) {
       execlp(command, command, NULL);
       printf("here rtn is %d\n", rtn);            //这一句居然不执行,  不知为何, 其但求在接下来的学习可以获知
       perror ( command );
       exit(-1);
    } else {
       wait (&rtn);
       printf("child process return %d\n", rtn);
    }
  }
  return 0;
}

P.S. 编译时要用g++

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值