linux高级编程 进程控制与描述

进程的组成

在这里插入图片描述

未运行的程序是没有栈和堆的。
在这里插入图片描述>程序是由下至上编译,static在只读区,所以不能将变量对其进行初始化。
int a =10;
static b = a;
这样写会报错
在这里插入图片描述

linux 进程表示

/usr/src/linux-headers-5.4.0-150-generic/include/linux/sched.h
在linux库文件中库找到linux的进程状态函数的变量表示
进程状态原始3种, unrunnable (不运行) runable
state 进程状态
在这里插入图片描述
volatile 活跃的,由该关键字声明的变量,是直接读取寄存器存储值,转换速度很快.

linux 进程状态

运行态®
睡眠态()

可中断睡眠interrupt(S)
不可中断睡眠uninterrupt(D)

停止态(T)
僵尸态(Z)
在这里插入图片描述

进程命令

ps(process status)
ps -ef 用来获取进程的PID号
在这里插入图片描述ps -aux 多出stat 状态表示有+号在前台运行, 无+号在后台运行.
在这里插入图片描述oneko & 在命令后加&可以将程序放在后台运行
在这里插入图片描述

bg (background)将进程放在后台运行

fg(foreground)将后台进程放置在前台运行

linux创建子进程

#include <unistd.和>
pid_t fork() (fork 叉)
成功父进程返回0, 子进程返回PID
失败返回-1 并至errno

linux 创建子线程

头文件 #include <pthread.h>
再进行编译时需要使用 gcc thread_demo.c -lpthread
链接pthread库才可以正常运行

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                     void *(*start_routine) (void *), void *arg);

参数 :
thread : 使用pthread_t 声明的tid
attr : 配置

在这里插入图片描述线程退出

pthrea_exit()
当该函数再主进程中使用pthread_exit()时主进程退出, 线程还在运行,只有当所有线程退出时进程才会结束.

等待线程退出

void * val; pthread_join(tid,&val);
使用二级指针接收函数传递回来的一级指针.
若线程tid没有退着阻塞调用pthread_join()的线程

分离式线程

pthread_detach()
由操作系统释放资源

取消线程

pthread_canael()
结束其他线程,

线程同步

线程的同步就是使用信号量.

信号量

初始化型号量(em)

sem_init()
在这里插入图片描述
@sem信号量地址
@pshared :0 线程间使用: !0进程间使用
@value:初始值
成功返回0;失败返回-1;

P V操作

sem_wait() 若sem信号为!0着递减, 为0着阻塞
在这里插入图片描述
sem_post()对sem的信号量进行增量操作, !0着另外一个使用sem_wait()阻塞的程序将会被唤醒, 然后锁定.
在这里插入图片描述

互斥锁(mutex)

使用POSIX的库
再man 中无法直接查询, 需要额外安装POSIX的相关手册

apt-get install manpages-posix-dev

变量定义

pthread_mutex_t mutex
在这里插入图片描述

初始化

pthread_mutex_init()
在这里插入图片描述
pthread_mutex_destroy() 该函数会销毁互斥锁.
可直接使用PTHREAD_MUTEX_INITIALIZER宏来进行直接赋值的快速初始化

mutex 获得 和 释放

pthread_mutex_lock();
在这里插入图片描述
若该锁处于互斥锁属于上锁状态, 将会阻塞线程.
pthread_mutex_unlock();会释放已加锁的mutex

条件变量

使用线程公用的全局变量进行同步通讯
定义变量

pthread_cond_t cond;
在这里插入图片描述>

初始化

ptread_cond_init(&cond, NULL);

等待条件变量

pthread_cond_wait()

唤醒等待进程

pthread_cond_brodercast()
pthread_cond_signal()

管道

无名管道

@只能用于亲缘进程才可以使用
int fd[2];
int pipe(fd); 创建管道
fd[0] 表示read
fd[1] 表示write在这里插入图片描述

有名管道

在命令行处可以使用mkfifo进行创建

管道文件是个数据缓冲区, 不行空间大小将会一直为0;
在这里插入图片描述

在程序中创建

在这里插入图片描述

信号

linux信号发送

kill()
在这里插入图片描述
raise()
给当前线程发送信号
在这里插入图片描述
alarm()
闹钟函数, 当定时器指定是实现到后,系统会想进程发送SIGALARM信号
注意: 一个进程只能使用一个闹钟函数, 多次使用将会刷新时间,
在这里插入图片描述

linux信号捕捉

函数睡眠等待使用pause();
自定义处理信号
if(signal(STGINT, sig_hander)!=SIG_ERR);
在主线程中使用signal(SIGCHLD,SIG_IGN)忽略子线程的信号,可以不使用wait()就将线程进行释放.
主要是因为子线程会被转给init进程, 这样就不会产生僵尸子进程.
在这里插入图片描述

信号名 含义

在这里插入图片描述

ftok

该函数使用一个可访问的文件, 和一个proj_id 低八位的字符来创建 key
该key可以适用于msgget() (消息队列创建)semget()(信号量集合创建)shmget()(共享内存创建)
在这里插入图片描述

消息队列

队列创建

msgget()
key 值由 ftok()函数生成
返回消息id
在这里插入图片描述

发送消息

msgsnd()
在这里插入图片描述

接收信息

msgrcv()
在这里插入图片描述

消息队列控制

msgctl()
cmd 参数
①IPC_RMID 删除消息队列
②IPC_STAT 获取消息队列信息
③IPC_SET 设置消息队列信息
在这里插入图片描述

共享内存

多个进程访问同一块内存空间
创建共享内存

shmget()
在这里插入图片描述

建立映射

shmat()
在这里插入图片描述

解除映射

shmdt()
在这里插入图片描述

控制

shmctl()
在这里插入图片描述

信号量操作API

信号量集合创建
semget()
在这里插入图片描述

信号量控制
semctl()
在这里插入图片描述

信号量操作
semop()
在这里插入图片描述

kill 使用

在这里插入图片描述

注意

①缓冲区一般使用环形队列 (先进先出)
②有了进程为什么需要线程

程序的执行可以理解为上下文的切换(保存老进程的cpu运行状态,加载新进程),
进程之间的切换对系统的开销很大,而后就创建了线程,它允许将进程的资源从主体中剥离出来,
允许与其他线程共享资源.

一个程序至少有一个进程, 一个进程至少有一个线程.
进程是资源管理的最小单位
线程是程序执行的最小单位

END

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值