进程的退出 | 线程

进程的退出

1.wait   pid_t wait(int *wstatus);

功能:

1.获取子进程退出状态,

2.回收资源 //会让僵尸态的子进程销毁

注:

1.wait本身是一个阻塞操作,会使调用者阻塞。

2.//在被调函数中修改主调

3. WIFEXITED 判断是否正常退出 。

4.WEXITSTATUS用于从wait系统调用的返回值中提取子进程的退出状态。这种状态是子进程通过exit或_exit调用,或在main函数的返回语句中指定的。只有在WIFEXITED宏返回真时,即子进程正常退出时,才应使用WEXITSTATUS。

5.父进程要获得子进程的退出状态——exit(退出状态值) 0~255;父进程调用wait()获取到退出状态值。

2.waitpid     pid_t waitpid(pid_t pid, int *wstatus, int options);

功能:等待子进程状态发生变化

参数:pid>0 表示等待指定的子进程状态的变化 ,传入指定pid号

pid = -1  表示等待所有子进程状态的变化

*wstatus 表示获取到子进程状态信息

options  :WNOHANG  默认是阻塞0

阻塞和非阻塞

1.阻塞:会影响父进程处理逻辑

2.非阻塞:父进程会去查看子进程状态改变。但是若没有发生改变,父进程也不会阻塞,整个程序继续往下,非阻塞必须套在循环中,阻塞会影响父进程处理逻辑。

总结:
1.wait 和 waitpid都是 等待子进程状态改变

2.wait是一种阻塞调用

3.waitpid 可以实现非阻塞调用

#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <signal.h>
#if 0
int main()
{
    pid_t pid = fork();
    if(-1 == pid)
    {
        perror("forkk error\n");
        return 1;
    }
    if(pid > 0)
    {
        int i;
       // wait(&i);
        waitpid(-1,&i,0);
        /*  if(WIFEXITED(i))
        {
        printf("father = %d\n",WEXITSTATUS(i));  
    }*/
        if(WIFSIGNALED(i)) //异常结束
        {
            printf("kill num = %d\n",WTERMSIG(i));
        }
    }
    if( 0 == pid)
    {

        printf("child pid = %d \n",getpid());
        // exit(255);//正常结束
        //        sighandler_t signal(int signum, sighandler_t handler);

        //  signal()
        while(1)
        {      
            sleep(1);
        }
    }
 //   return 99; //正常结束
 //   }
    return 0;
}

线程:

1.什么是线程?

线程:轻量级的进程

2.为什么需要线程?

线程成为cpu执行的最小单位。

进程成为资源分配的基本单位。

线程创建和调度时空开销都比进程小

3.线程组成

4.线程与进程的关系

  1. 线程是存在于进程中的
  2. 线程共享了进程的资源(代码段,数据段,打开一些文件)
  3. 线程结束不一定导致进程结束
线程的创建:编译时需要加 -lpathread

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

参数:

pthread_t *thread:线程id,一般为长整型。

const pthread_attr_t *attr:属性:默认(可结合性)---自己手动回收  分离属性—系统自动回收

void *(*start_routine) (void *): 一个指针函数的函数指针

void *arg:线程的执行空间,可以为NULL

注:

1.主函数所在的执行流为主线程

2.其他线程为子线程/次线程

3.pthread_self 在哪个线程调用,获取的就是哪个线程的tid号无固定 顺序

4.线程执行函数传参:

线程的执行 体现在回调函数上

线程的退出:

pthread_exit()

功能:结束调用的线程

参数:退出状态值对应的地址

注意:

1.如果在主函数中,表示结束主线程。

2.主线程结束并不表示进程结束。

线程的资源回收:

 int pthread_join(pthread_t thread, void **retval);
功能: 等待线程结束
参数:
pthread_t thread :线程tid
void **retval:用来保存,退出状态值,所在空间的地址
返回值:
成功0失败错误码

注:
线程退出时,可以带出退出状态值,但传的是,退出状态值对应空间的地址

传地址和值

#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>

void * do_something(void *arg)
{
	static int a = 10;
	//线程的任务函数 
	printf("------do_something ---- \n");

	//pthread_exit(NULL);
	pthread_exit(&a);
	//pthread_exit((void *)a);
}

int main(int argc, const char *argv[])
{
	pthread_t tid;
	int ret = pthread_create(&tid,NULL,do_something,NULL);

	if (ret != 0)
	{
		errno = ret;
		perror("pthread_create fail");
		return -1;
	}

	//sleep(3);
   void *retval; 
	//pthread_join(tid,&retval);
	pthread_join(tid,&retval);


	printf("---- main----%d\n",*(int *)retval);
//	printf("---- main----%d\n",(int)retval);

	pthread_exit(NULL);

	return 0;
}

传字符串

#include<stdio.h>
#include <pthread.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
void * do_something(void *arg)
{
   /* char *a = malloc(512 * sizeof(char));
    if(a != NULL)
    {
        strcpy(a,"hello");
    }*/
    char *a = "hello";
    printf("------do_something ---- \n");
    pthread_exit(a);

}
int main(int argc, const char *argv[])
{
    pthread_t tid;
    int ret = pthread_create(&tid,NULL,do_something,NULL);

    if (ret != 0)
    {
        errno = ret;
        perror("pthread_create fail");
        return -1;
    }
    void *retval; 
    pthread_join(tid,&retval);
    printf("---- main----%s\n",(char *)retval);
    pthread_exit(NULL);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值