进程与线程总结

进程
进程是动态的,消耗内存、cup资源。程序结束时资源就释放,即进程死亡。

进程的状态
进程有五个状态:
①就绪态:当一个进程被创建出来后,但还未获得(时间片)时,该进程就为就绪态。
②执行态:获得时间片,CPU的使用权
③睡眠态:用户调用sleep函数,usleep函数 (睡眠函数)。
④暂停态:用户发送暂停信号(kill -19 进程ID)
⑤僵尸态:进程死亡就会进入到僵尸态 (主函数调用return ,调用exit,被信号杀死…)
系统分配资源的最少单位是进程(内存空间)

子进程拿到父进程的资源有如下:
1.用户ID和组ID
2.所有的环境变量
3.进程组ID 会话ID
4.当前的工作路径
5.打开的文件描述符与文件指针
6.信号函数
7.整个内存空间

不拷贝的如下:
1.进程PID号
2.记录锁
3.暂停信号

创建一个进程
pid_t fork(void);
返回值大于0即父进程
返回值等于0即子进程

int main()
{

    //创建一个子进程  
	pid_t  pid = fork();
		  if(pid == 0)  //子进程
		  {	
			int i=0;
			for(i=0;i<3;i++)
			{
			 printf("hello\n"); 
			}
		  } 
		  if(pid > 0) //父进程
		  {
			//先让父亲进程睡眠
			sleep(1);
			printf("world\n");   
		  }
}

获得进程的id号
pid_t getpid(void)获取当前
pid_t getppid(void) 获取父进程

等待某一进程退出
pid_t waitpid(pid_t pid,int *wstatus,int options);
arg1 等待的进程pid
arg2 退出状态
arg3 属性 (0/WNOHANG)(一直等待/等待一下)

wstatus 进程的退出状态值
WIFEXITED(wstatus) //判断是否为正常退出
WEXITSTATUS(wstatus) //获取正常退出的值 (return 的值) 不能超过8位 最大为255
WIFSIGNALED(wstatus) //被信号杀死
WTERMSIG(wstatus) //获取杀死他的信号值
WIFSTOPPED(wstatus) //被信号暂停 WSTOPSIG(wstatus)//获取暂停的值

退出进程
void exit(int status);
该函数退出时会回收资源
void _exit(int status);
该函数退出时不会回收资源
int status参数与return后的值一样(多为0??)

execl族函数
使子进程去执行别的程序
int execl(const char *path,const char *arg,NULL)
arg1 绝对路径
arg2 可执行程序的参数(int argc,char *argv[])
arg3 NULL

int execv(const char *path, const char *argv[]); //与上述功能一致,只不过这个传递的是数组指针
参数一:可执行文件的路径 (绝对路径)
参数二:传递给任务函数的参数 (字符串指针数组,注意该数组末尾必须为NULL)

int execle(const char *path, const char *arg, …, (char *) NULL, char * const envp[] */); //可以附加环境变量

自动传递主进程的环境变量给子进程使用 (带环境的,可以不用写绝对路径)
int execlp(const char *file, const char arg, …
/
(char *) NULL */);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
char *const envp[]);

system
int system(const char *command);
该函数会自己创建一个进程去执行命令
——————————————————————————

线程
线程和进程的区别
进程:是系统分配资源的最少单位(分配虚拟内存)
线程:是系统调度的最少单位(分配时间片)

线程其实也需要资源的,那么线程的资源是从进程里面获取的,(虚拟内存有,数据段
代码段,堆,栈)那么我们线程与进程共享所有资源,除了自己的虚拟栈。

创建线程 pthread_create
等待线程 pthread_join
退出线程 pthread_exit

 //全局变量
int poin = 100; 
 
//子线程
void *func(void *arg)
{

	while(1)
	{
	  printf("func_poin=%d\n",poin++);
	  sleep(1);
	  if(poin == 105)
	  {
		  //线程退出
		 pthread_exit(NULL);
	  }
	}
}

int main()
{
	int a=100;

	printf("main_poin=%d\n",poin);

	//创建一个任务线程
	pthread_t tid=0;			
	pthread_create(&tid,NULL,func,(void *)&a);
	
	
	//设置为分离属性  自己回收资源
	//pthread_detach(tid);
	
	printf("main_poin=%d\n",poin++);
	printf("等待子线程结束\n");
	
	//pthread_join(tid,NULL); //回收线程的资源
	while(1);
	printf("等待子线程结束完毕!!\n");

}

线程属性设置
设置/获取线程的栈大小

void *func(void *arg)
{
    printf("runing\n");
}

int main()
{
	//创建一个线程
	pthread_t tid=0;		
    pthread_attr_t attr;
	bzero(&attr,sizeof(attr));
	
	//设置栈空间的大小
	int ret = pthread_attr_setstacksize(&attr,16384*4);
		if(ret != 0)
		{
			perror("set fail\n");
			exit(0);
		}
	//设置完毕后创建!!
	pthread_create(&tid,&attr,func,NULL);
	 size_t size;
	//获取栈的大小 
    pthread_attr_getstacksize(&attr,&size);
	printf("size=%lu\n",size);
	pthread_join(tid,NULL);
}

设置线程为分离属性,让线程自己回收自己的资源
int pthrea_detach(pthread_t thread);

使用线程注意事项:
1.主线程结束,所有的子线程都会死亡。
2.全局变量与线程中的局部变量同名则优先使用局部变量。
3.所有的线程共享全局变量,线程之间的通信只需要使用全局变量即可!!
4.当一个线程被设置为分离属性后,他就自己回收资源,pthread_join等待失效。

线程的取消与线程的取消处理函数

 //全局变量
int poin = 100; 
 
//子线程
void *func(void *arg)
{
	//关闭取消请求
	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
	while(1)
	{
	  printf("func_poin=%d\n",poin++);
	  
	  if(poin == 110)
	  {
		//重新开启取消请求
		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
	  }
	  sleep(1);
	}
}
//取消处理函数
void del(void *arg)
{
	printf("已经把线程处理完毕啦!!\n");
}

int main()
{
	//创建一个任务线程
	pthread_t tid=0;			
	pthread_create(&tid,NULL,func,NULL);
	pthread_cleanup_push(del,NULL); //注册线程取消处理函数
	printf("等待子线程结束\n");
	while(1)
	{
		int a=0;
		scanf("%d",&a);
		if(a== 886)
		{
		//线程取消信号 
		pthread_cancel(tid);
		break;
		}	
	}
	pthread_cleanup_pop(0);//启动取消处理函数  自动去执行 注册好的函数
	pthread_join(tid,NULL); //回收线程的资源
	printf("等待子线程结束完毕!!\n");
}

线程的互斥锁
保护各个线程中的共享资源
互斥锁要定义为全局变量

 //全局变量
int poin = 100;   //共享资源
 
pthread_mutex_t mutex;  //定义为全局变量,在所有线程中有效 
 
//子线程 
void *func(void *arg)
{
	while(1)
	{
	
	  //执行上锁操作
	  pthread_mutex_lock(&mutex);
	  //处理共享资源
	  printf("func_poin=%d\n",poin);
	  pthread_mutex_unlock(&mutex);
	}
}

int main()
{
	int a=100;

	printf("main_poin=%d\n",poin);

	//初始化线程锁 
	pthread_mutex_init(&mutex,NULL);
	
	//创建一个任务线程
	pthread_t tid=0;			
	pthread_create(&tid,NULL,func,(void *)&a);
	
	//设置为分离属性  自己回收资源
	pthread_detach(tid);
	while(1)
	{
		//执行上锁操作
		pthread_mutex_lock(&mutex);
		//修改共享资源
     	printf("main_poin=%d\n",poin++);
	    pthread_mutex_unlock(&mutex);
	}
}

线程的条件变量
使各个线程之间协调工作,使用时必须配合互斥锁

 //全局变量
int poin = 100;   //共享资源
 
pthread_mutex_t mutex;  //定义为全局变量,在所有线程中有效 
pthread_cond_t  cond;   //定义为全局变量,使他在所有线程中有效
 
//子线程 
void *func(void *arg)
{

	while(1)
	{
	  //执行上锁操作
	  pthread_mutex_lock(&mutex);
	  printf("wati…………………………………………\n");
	  //等待主线程唤醒 设置一个条件变量
	  pthread_cond_wait(&cond,&mutex);       //这把锁还是正在上锁的!!!!!
	  printf("wati………………OFF…………………\n");
	  
	  //处理共享资源
	  printf("func_poin=%d\n",poin);
	  printf("mutex\n");	  
	  pthread_mutex_unlock(&mutex);
	}
}

int main()
{
	//初始化线程锁 
	pthread_mutex_init(&mutex,NULL);
	
	//初始化条件变量 
	pthread_cond_init(&cond,NULL);
	//创建一个任务线程
	pthread_t tid=0;			
	pthread_create(&tid,NULL,func,NULL);
	
	//设置为分离属性  自己回收资源
	pthread_detach(tid);
	
	while(1)
	{
		int a=0;
		scanf("%d",&a);
		if(a == 1)
		{
			//发送一个条件变量
			pthread_cond_signal(&cond);	
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值