目录

wait --> pid_t wait(int *wstatus);        #include

waitpid --> pid_t  waitpid(pid_t   pid,   int   *wstatus,   int  options);         #include         #include

线程

线程的创建        pthread_create        (3)库函数        #include


wait --> pid_t wait(int *wstatus);        #include <sys/wait.h>

功能:等待子进程状态改变,但是这里我们研究的是子进程的退出

参数:@wstatus:用来保存子进程退出的状态值的

返回值

  • 成功返回 结束了的子进程的PID
  • 失败返回 -1

注意:

  • wait函数是一个阻塞操作,等当前进程的任意子进程结束
  • wait一次只能处理一个子进程

会传给父进程,而父进程可以通过wait或waitpid的wstatus来获得
注意
要获得退出状态值需要使用宏才能获取WIFEXITED(wstatus)//判断子进程是否时正常结束WEXITSTATUS(wstatus)//获取子进程退出状态WIFSIGNALED(wstatus)//判断子进程是否是信号结束的WTERMSIG(wstatus)//获得结束的信号编号

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>

int main(int argc,const char *argv[])
{
	//(1) f
	printf("test fork\n");
	pid_t pid = fork();
	if(pid < 0)
	{
		perror("fork fail");
		return -1;
	}
	//(2) f and c
	printf("main pid = %d\n",pid);
	//(3) f
	if(pid > 0)
	{
		while(1)
		{
			printf("f pid = %d\n", getpid());
			sleep(1);
			int wstatus;
			if(wait(&wstatus) < 0)	//回收资源
			{
				perror("wait fail");
				return -1;
			}
			if(WIFEXITED(wstatus))
			{
				printf("child exit status = %d\n",WEXITSTATUS(wstatus));
			}
		}
	}
	//(4) c
	else if(pid == 0)
	{
		int i = 0;
		while(i < 5)
		{
			printf("c pid = %d\n",getpid());
			sleep(1);
			++i;
		}
		exit(99);
	}
	return 0;
}

在之前的代码中添加信号在只有父进程要做的事里面

if(WIFEXITED(wstatus))
{
	printf("child exit status = %d\n",WEXITSTATUS(wstatus));
}
if(WIFSIGNALED(wstatus))
{
	printf("child exit signal = %d\n",WTERMSIG(wstatus));
}

每个子进程退出时带出一个状态,父进程可以根据状态来判断是哪个子进程

waitpid --> pid_t  waitpid(pid_t   pid,   int   *wstatus,   int  options);         #include <sys/types.h>        #include <sys/wait.h>

功能:等待子进程状态改变(退出)

参数: @wstatus //用来保存 子进程退出的状态值的

返回值:

  • 成功        返回结束了的子进程的pid
  • 失败        返回-1

线程

线程 被称为 轻量级线程,之前我们学习的算重量级线程,轻量和重量主要在于资源的占用

创建进程和创建线程

  • 进程 = PCB + |堆栈|bss|data|text|
  • 线程 = 线程ID + 程序计数器|寄存器集合|栈

线程与进程的关系

  1. 在线程出现以后,线程变成了CPU调度执行的最小单位(侧重于执行的单位),进程是资源分配的最小单位(侧重于资源分配的单位)
  2. 线程的创建和切换(调度)效率高于进程
  3. 线程依附于进程,线程是存在于进程的空间,进程不存在则线程也不存在;多个线程共享了进程资源,代码段,数据段,打开的文件等

在linux内核中,实际上是不区分进程和线程的,统一被称为任务--task,Linux为了支持线程编程 -- linux thread //thread编程

red hat -- 韩国 -- linux -- NPTL(线程库)

ibm -- 美国早计算机的公司

线程的创建        pthread_create        (3)库函数        #include <pthread.h>

pthread_create --> int pthread_create(pthread_t *thread, //线程id        

                              const pthread_attr_t *attr, //线程属性 NULL 默认属性

                              void *(*start_routine) (void *), // 线程回调函数(执行函数)

                              void *arg // arg );表示传递给线程执行

功能:创建线程

返回值:

  • 成功        返回0
  • 失败        返回错误码

注意:

  • 使用线程库时,编译时记得要在gcc后面链接上 pthread 库        gcc thread.c -lpthread
  • 线程创建好之后,此时有两个执行流,一个是主函数所在的执行流(主线程),一个是子线程所在的执行流(子线程/次线程)
  • 在线程中,线程之间关系是对等
  • 线程共享了进程资源:数据段,全局变量,局部变量,堆区变量,因为共享时如果使用的是同一个变量, 那么多个线程之间会有相互影响
  • 线程创建好之后,线程的运行顺序也是不确定的 最终都需要由操作系统来调度 
  • 线程共享数据方便,如果是想让多线程相互影响同一个数据,那么传参的时候需要传地址做*运算,如果多线程使用同一个初值,但是各自操作各自,那么想办法获得值
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>

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

int main(int argc,const char *argv[])
{
	pthread_t tid;
	int ret = pthread_create(&tid,NULL,do_sth,NULL);
	if(ret != 0)
	{
        errno = ret;   //errno 系统的一个全局变量,用来存放全局的错误码
		perror("pthread_create error");
		return -1;
	}

	printf("main \n");
	sleep(3);
	return 0;
}
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>

void * do_sth1(void *arg)
{
	int a = *(int *)arg;
	while(1)
	{
		a++;
		printf("a1 = %d\n",a);
		sleep(1);
	}
	return NULL;
}

void * do_sth2(void *arg)
{
	int a =*(int *)arg;
	while(1)
	{
		a+=2;
		printf("a2 = %d\n",a);
		sleep(1);
	}
	return NULL;
}

int main(int argc,const char *argv[])
{
	int a = 0;
	pthread_t tid[2];
	//1
	int ret = pthread_create(&tid[0],NULL,do_sth1,&a);
	if(ret != 0)
	{
		errno = ret;	//errno 系统的一个全局变量,用来存放全局的错误码
		perror("pthread_create error");
		return -1;
	}
	//2
	ret = pthread_create(&tid[1],NULL,do_sth2,&a);
	if(ret != 0)
	{
		errno = ret;	//errno 系统的一个全局变量,用来存放全局的错误码
		perror("pthread_create error");
		return -1;
	}

//	printf("main \n");
	while(1)
		sleep(1);
	return 0;
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐