进线程ing

(给自己看的笔记ing……)


进程

程序:静态的、可执行的二进制文件。存在磁盘

进程:动态的,启动-》调度-》凋亡。存在内存

        定义:一个程序从启动到调度到凋亡的整个过程成为进程

进程的状态

        运行:R

        停止:T

        等待:S

        僵尸:Z(资源没有被回收,没有任何作用,还要占用内存,所以子进程结束一定要进行资源回收)孤儿进程(父亲先结束)-》会被init收养

Linux 进程管理(用户软件)

        会话    使用某个会话创建的进程,属于会话管理,不是所有的进程都需依赖会话

        进程组

        进程

        ps -aux 查看进程静态状态

        top        动态监测

        jobs        查看后台进程

        ./a.out  &        放于后台执行

        bg        放于后台执行

        ctrl +z         挂起进程

        fg         放于前台执行

        kill        向进程发送信号,默认发送的信号是-9

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

fork()

        为社么可以有两个返回值:开辟了一个子进程,子进程和父进程各有一个返回值

        复制什么东西:用户空间(包含缓存区)

exit()推出进程

#include <stdlib.h>

void exit(int status);        \\刷新缓存

void _exit(int status);        \\不刷新缓存

第一次hello是父进程结束,但是子进程没完成继续跑,跑完为止,所以子进程成为了孤儿进程

孤儿进程:

        避免出现,让父进程等待子进程结束再推出

僵尸进程:

        一定避免出现,让父进程帮助回收子进程

wait        #include <sys/types.h> #include<sys/wait.h>

pid_t wait (int *status);        //不再进行下面的语句

参数:status退出状态

pid_t waitpid(pid_t pid,int* status,int options);        //可以做其他的事情,

功能:回收子进程资源 可以设置非阻塞         

返回值:成功pid,失败-1,0非阻塞

参数:pid>0 回收子进程id等于pid的进程         pid=-1 回收任意子进程         pid=0 回收同组任意子进程         pid<-1 回收组id为-pid的任意子进程         status 接收退出状态

options: WNOHANG 非阻塞 0

此时s能够接收子进程的退出状态是0   ,存的是子进程的pid

进程分类

        交互进程
        守护进程  (确定条件:不依赖终端,通常情况:开机执行(配置内核脚本))

                日志系统

                服务器

                更新

                制作:(不依赖终端,就不从终端输入输出)

                        开辟一个孤儿进程(拉高权限,能独立处理不受其他影响;创建一个子进程,父进程结束 fork exit)    

                        创建新的会话(setsid)

                        更改工作目录(更改到权限更高的目录下比如 /根目录) chdir()

                        修改文件掩码        umask()

                        关闭不用的文件描述符  close()(默认一般有0、1、2三个描述符,     输入输出错误处理)     

exec函数族

l:列举,第二个参数需要列举出来  NULL结尾

p:环境变量查找,可以没有路径,第一个变参数可以在环境变量搜索

v:构造指向参数的指针数组

e:用新的环境变量来代替进程的环境变量,多一个参数,可以使用指针数组传递自定义的环境变量

线程

线程轻量级,

线程之间相互容易影响,进程之间相对稳定

vfork()

        子进程先执行

        空间共用

pthread_create :不属于标准库,gcc时加标准库,成功返回0  不成功返回非0

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);
参数1:线程id

参数2:NULL

参数3:线程函数指针

参数4 :参数

void pthread_exit(void *retval);

功能:退出线程        返回值:无        参数:retaval,返回的状态

int0(pthread_t thread, void **retval);

功能:等待某个线程结束        返回值:0成功        参数:thread 线程id        retavl:接受退出状态(阻塞等待)

练习:父进程:创建一个子进程,每秒打印一个hello

           父进程:创建一个子进程,调用该ls

           父进程:创建一个子进程,接受标准输入A创建一个线程每秒打印一个数字(1)

                                                               B结束所有开辟出来的线程

结合属性:需要主动回收(要做其他事情)用join

分离属性:自己回收(不做其他事情)用detach

int pthread_detach(pthread_t thread);

功能:线程分离,分离之后线程结束自动回收资源        返回值:0成功        参数:thread线程id

  • 共享内存: 在多线程程序中,如果多个线程访问同一个内存位置(如全局变量 data),那么这些线程就是在共享内存。当一个线程修改了内存中的值,其他线程可以立即看到这些修改。

线程通信

线程通信

        使用全局变量进行通信

互斥

        互斥锁实现互斥,在创建线程之前,所以访问共有的资源要互斥

创建一个互斥锁:

pthread_mutex_t mutex;        //全局变量(所有的线程都要用)

初始化:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr) 

返回值:0正确        参数mutex:锁        attr:属性  默认NULL      

上锁:

int pthread_mutex_lock(pthread_mutex_t *mutex) //加锁,获取不到锁会挂起

返回值:0正确        参数mutex:锁 

解锁:

int pthread_mutex_unlock(pthread_mutex_t *mutex) //解锁

返回值:0正确        参数mutex:锁 

销毁:

int pthread_mutex_destory(pthread_mutex_t *mutex) 

返回值:0正确        参数mutex:锁 

尝试锁:

int pthread_mutex_trylock(pthread_mutex_t *mutex) 

返回值:EBUSY 被占用        参数mutex:锁 

同步

可以规定执行的顺序,但是不是说一人一次(只规定谁先谁后)

#include <semaphore.h>

创建信号量:

        sem_t sem

初始化信号量:

        int sem_init(sem_t *sem, int pshared, unsigned int value);

        参数:sem:信号量        pshared: 0进程和线程通信        value>=0        返回值:0和-1

v操作:

         int sem_post(sem_t *sem);

        功能:生产 +1        返回值0和-1        参数sem:信号量

p操作:

         int sem_waitt(sem_t *sem);

        功能:消费 -1        返回值0和-1        参数sem:信号量

  想通信要一人一次:可以设置信号量的值,比如r_sem、w_sem....

……………………

进程通信

管道通信

        无名管道:

                用于具有亲缘关系的进程之间即组id相同;具有固定的读端和写端,是半双工通信,无名管道是一种特殊的文件,使用IO操作。

#include <unistd.h>            

         int pipe(int pipefd[2]);

        功能:        参数:pipfd:包含两个元素的整型数组        返回值:0成功-1失败

        fd[0]用于固定的读        fd[1]用于固定的写

在写端没有关掉的时候会出现阻塞状态等待写操作,但是 写端关掉读端不会阻塞

        有名管道:

                用于任意管道之间即进程的组id不同

#include <sys/types.h>        

作业:

        1.用有名管道实现非亲缘进程的通信

        2.创建两个子进程,父进程负责回收资源

        子进程1,负责给子进程2发送指令

        子进程2,接受指令

                        指令1,开辟两个线程,线程2给全局变量赋值A-Z,线程2顺序打印,打印一次就退出两个线程(考虑资源回收问题)

                        指令2,子进程2结束,子进程1结束,父进程打印推出信息回收资源

信号

ipc对象通信

        内存共享

最快的进程通信方式,支持亲缘或者是非亲缘通信

               1、 创建/打开共享内存 ftok

                key_t ftok( char *pathname, int n);

                功能:返回一个唯一不重复标识

                返回值:失败-1 成功key

                参数:pathname 路径        n:数值,一般使用字符

                int shmget(ket_t key, int size ,int flag)

                功能:创建/打开一个共享内存

                返回值:

                参数:key值        size:共享内存的大小        flag: IPC_CREAT   IPC_EXCL    0666

                2、映射共享内存

                void *shmdt(int shmid ,void *shmaddr, int shmflag);

                功能: 映射共享内存

                返回值:成功返回映射的地址,失败(void)* -1

                参数:shmid: 共享内存id

                           shmaddr:NULL系统分配

                           shmflg: 0默认读写 SHM_RDONLY

                        3、操作内存(读写操作)

                4、取消共享内存映射

                void * shmdt(const void *shmaddr);

                功能:取消映射

                返回值:成功0        失败-1

                参数:被映射的地址

                5、删除共享内存对象

                int shmctl (int shmid , int cmd , struct shmid_ds *buf );

                功能:操作共享内存

                返回值:成功0        失败-1

                参数:shmid:共享内存id

                           cmd:IPC_STST(获取对象属性)

                                      IPC_SET(设置对象属性) 

                                      IPC_RMID(删除对象)

                            buf:删除  可以填NULL

ipcs -m:显示当前的共享内存

        信号灯集

配合共享内存使用实现共享和互斥

        消息队列

#include <sys/msg.h> #include <sys/types.h> #include<sys/ipc.h>       

创建/打开消息队列 msgget

函数定义: int msgget(key_t key, int msgflg);

        函数参数: key:IPC_PRIVATE ftok的返回值

                        shmflg:权限位

                        IPC_CREAT:如果不存在则创建一个

                        IPC_EXCL:确保创建一个新的消息队列,否则失败

         返回值:消息队列ID

函数定义: int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

        函数参数:

                msqid:消息队列ID

                msgp:消息结构体指针

                msgsz:消息结构体数据大小

                msgflg: IPC_NOWAIT 消息没有发送完成函数也会立即返 回。

                        0:直到发送完成函数才返回

        返回值:成功返回0,失败-1msgrcv

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

        函数参数:

                msqid:消息队列ID

                msgp:消息结构体指针

                msgsz:消息结构体数据大小,如果接收的数据大于msgsz 则会截取数据

                msgtyp: 0:接收第一个

                                >0:接收指定typemsgtyp的消息

                                <0:接收消息队列中类型值不小于msgtyp的绝对值 且类型值又最小的消息。

                msgflg: 0:若无消息函数会一直阻塞

                                IPC_NOWAIT:若没有消息,进程会立即返回ENOMSG

                返回值:成功返回字节数函数定义:

.销毁消息队列 msgctl

函数定义: int shmctl(int shmid, int cmd, struct shmid_ds *buf);

        函数参数: shmid:要映射的共享内存区标识符

                           cmd:

                                        IPC_STAT:获取内存段状态

                                        IPC_SET:设置内存段信息

                                        IPC_RMID:销毁内存段

         返回值:成功返回02.添加消息/读取消息 msgsnd/msgrcv

思考:什么是死锁?
           怎么去防止死锁?

        套接字socket(网络编程)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值