文章目录
进程的组成
未运行的程序是没有栈和堆的。
>程序是由下至上编译,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