目录
1.进程:
程序:编译好的可执行文件
存放在磁盘上的指令和数据的有序集合(文件)
程序是静态的,没有任何执行的概念
进程:一个独立的可调度的任务
执行一个程序所分配的资源的总称
进程是程序的一次执行过程
进程是动态的,包括创建、调度、执行和消亡
1)“数据段”存放的是全局变量、常数以及动态数据分配的数据空间
(如malloc函数取得的空间)等。
2)“正文段”存放的是程序中的代码
3)“堆栈段”存放的是函数的返回地址、函数的参数以及程序中的局部变量
进程的类型:
1)交互进程:交互进程既可以在前台运行,也可以在后台运行。
该类进程经常与用户进行交互,需要等待用户的输入,当接收到用户的输入后,
该类进程会立刻响应。例如:ctrl+c
2)批处理进程:该类进程不属于某个终端,它被提交到一个队列中以便顺序执行
3)守护进程:该类进程在后台运行的特殊进程。它一般在Linux启动时开始执行,系统关闭时才结束,守护进程名通常以d结尾。
进程的运行状态:
1)运行态:此时进程或者正在运行,或者准备运行。
2)等待态:此时进程在等待一个事件的发生或某种系统资源。
可中断:处在这种状态下的进程可以被信号中断,接收到信号或被显示地唤醒呼叫,唤醒之后,进程将转变为运行态。
不可中断:它不会处理信号,只有在它所等待的事件发生时,进程才被显示的唤醒,
或者处于该状态的进程被使用wake_up()函数明确唤醒时才能转换到可运行的就绪状态。
3)停止态:此时进程被中止。
4)死亡态:这是一个已终止的进程,但还在进程向量数组中占有一个task_struct结构。
D uninterruptible sleep (usually IO)(不可中断的等待态)
R running or runnable (on run queue)(运行态)
S interruptible sleep (可中断的等待态)
T stopped, either by a job control signal or because it is
being traced.(停止态)
X dead (should never be seen)(死亡态)
Z defunct ("zombie") process, terminated but not reaped by its
parent.(僵尸态)
守护进程的创建:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#if 0
1.创建子进程,父进程退出,变为后台运行
2.将子进程脱离原会话组,独立于原会话成为新会话组组长
3.将当前工作目录改变为根目录
4.重设文件权限掩码
5.关闭不必要的文件描述符
#endif
int main(int argc, char *argv[])
{
pid_t pid;
pid = fork();
if(pid == 0)
{
int i,fd;
setsid();//创建新会话
chdir("/");//将当前的工作目录改变为根目录
umask(0);//将文件权限全部打开
for(i=0;i<getdtablesize();i++)
{
close(i);//关闭文件描述符
}
//每隔1秒往/tmp去写hello
fd = open("/tmp/test.log",O_WRONLY|O_CREAT|O_TRUNC,0777);
if(fd < 0 )
{
perror("open fail");
exit(-1);
}
while(1)
{
write(fd,"hello",5);
sleep(1);
}
close(fd);
}else if(pid > 0)
{
exit(0);
}else{
perror("fork err");
return -1;
}
return 0;
}
线程:
1.概念:线程指的是共享相同地址空间的多个任务(线程也有独立的空间--线程栈)
2.特点:
1)由于进程的地址空间是私有的,因此在进程间上下文切换时,系统开销比较大,线程的系统开销较小,不需要涉及资源切换
2)为了提高系统的性能,许多操作系统规范里引入了轻量级进程的概念,也被称为线程
3)在同一个进程中创建的线程共享该进程的地址空间
4)Linux里同样用task_struct来描述一个线程。线程和进程都参与统一的调度
3.优点:
1)使用多线程的好处大大提高了任务切换的效率
2)多线程通信简单,可以通过全局变量
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int flag=0;
char buf[32];
void * fun(void *arg)
{
while(1)
{
if(flag == 1)
{
printf("%s",buf);
if(strncmp(buf,"quit",4) == 0)
{
break;
}
memset(buf,0,sizeof(buf));
flag--;
}
}
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t tid;
if(pthread_create(&tid,NULL,fun,NULL) != 0)
{
perror("pthread_create err");
return -1;
}
while(1)
{
fgets(buf,sizeof(buf),stdin);
flag++;
if(strncmp(buf,"quit",4) == 0)
{
break;
}
}
pthread_join(tid,NULL);
return 0;
}
线程和进程的区别:
1)进程间相互独立,而同一个进程内的线程间共享进程内所有的资源
2)多线程间通信简单,但是需要对临界资源进行互斥与同步操作,多进程间通信较难
3)多线程安全性差,因为其中一个线程崩溃可能会对其他线程造成影响,多进程间相互独立,安全性高。
4) 线程执行效率高,进程执行效率低。
线程间同步:
同步的概念:多个任务(线程),按照约定顺序相互配合完成一件事情。
同步机制:信号量(sem)
1)信号量代表某一类资源,其值表示系统中该资源的数量
2)信号量是一个受保护的变量,只能通过三种操作来访问
初始化
P操作(申请资源):对资源进行减一操作
V操作(释放资源):对资源进行加一操作
3