Linux系统编程53 线程 - 线程标识的获取,比较,线程的创建,结束,收尸,线程栈清理

pthread_equal(),比较线程ID

NAME
       pthread_equal - compare thread IDs 比较两个线程ID

SYNOPSIS
       #include <pthread.h>

       int pthread_equal(pthread_t t1, pthread_t t2);
// 不清楚 线程ID 类型,不能直接按照int类型数值的比较方法。

用-pthread编译并链接。

如果两个线程id相等,则pthread_equal()返回一个非零值;否则,返回0。


pthread_self(), 获取当前线程的线程ID

NAME
       pthread_self - obtain ID of the calling thread

SYNOPSIS
       #include <pthread.h>

       pthread_t pthread_self(void);

       Compile and link with -pthread.

RETURN VALUE
       This function always succeeds, returning the calling thread's ID.

pthread_create() 线程的创建

NAME
pthread_create - create a new thread

SYNOPSIS
#include <pthread.h>

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

   Compile and link with -pthread.

RETURN VALUE
On success, pthread_create() returns 0; on error, it returns an error number, and the contents of *thread are undefined.

线程的调度取决于调度器的调度策略

由于pthread库不是标准linux库,所以编译 改为gcc thread.c -lpthread 即可。

实验1

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

static void* func(void* p)
{
	puts("Thread is working!");
	return NULL;
}

int main()
{
	pthread_t tid;
	int err;

	puts("Begin!");

	err = pthread_create(&tid,NULL,func,NULL);	
	if(err)
	{
		fprintf(stderr,"pthread_crearte():%s\n",strerror(err));
		exit(1);
	}

	puts("End!");
	exit(0);

}

mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ gcc pthread_create1.c  -lpthread
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ ./a.out 
Begin!
End!
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ 

线程的调度取决于调度器策略,在我们创建的线程还没来得及 调度的时候,当前进程就exit(0)结束了。


pthread_exit() 正常结束一个线程

线程的终止 的三种方式:
1 线程从启动例程返回,返回值就是线程的退出码
2 线程可以被同一进程中的其他线程取消
3 线程调动 pthread_exit()函数

NAME
       pthread_exit - terminate calling thread  正常结束一个线程

SYNOPSIS
       #include <pthread.h>

       void pthread_exit(void *retval);

       Compile and link with -pthread.


RETURN VALUE
       This function does not return to the caller.

与return 不同,调用 pthread_exit()结束线程 会实现线程栈的清理。


pthread_join():线程收尸

相当于 进程阶段的wait()操作,作用是 线程收尸,等一直等待线程运行结束 再收尸

和wait() 不同的时候 可以指定 收尸目标,wait()只有收到了 才知道收到的是谁。

NAME
       pthread_join - join with a terminated thread

SYNOPSIS
       #include <pthread.h>

       int pthread_join(pthread_t thread, void **retval);
//thread 指定收尸的目标线程
       // void **retval  为空,表示 只收尸,不关心状态 

       Compile and link with -pthread.

RETURN VALUE
On success, pthread_join() returns 0; on error, it returns an error number.

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

static void* func(void* p)
{
	puts("Thread is working!");	
	pthread_exit(NULL);
	//return NULL;
}

int main()
{
	pthread_t tid;
	int err;

	puts("Begin!");

	err = pthread_create(&tid,NULL,func,NULL);	
	if(err)
	{
		fprintf(stderr,"pthread_crearte():%s\n",strerror(err));
		exit(1);
	}

	pthread_join(tid,NULL);//线程收尸,一直等待线程结束后收尸
	puts("End!");
	exit(0);

}



mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ gcc pthread_create1.c -lpthread
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ ./a.out 
Begin!
Thread is working!
End!
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ 

可以看到 进程是等待 tid线程调度结束后 才结束进程,就是因为 pthread_join() 线程收尸函数, 一直在等待目标线程结束,后收尸。执行完收尸动作,进程才会exit(0) 结束进程。


栈的清理
pthread_cleanup_push()
pthread_cleanup_pop()

回顾:钩子函数 atexit(),在进程正常终止的时候,该函数将会被调用,并逆序调用挂在钩子上面的函数,这里的逆序调用挂载钩子上面的函数这个操作,我们无法介入,一定会被执行。

pthread_cleanup_push() 函数 类似于 atexit(),挂载钩子函数,而 pthread_cleanup_pop() 用于取下挂在钩子上面的函数,执不执行看参数,相比于 atexit()钩子函数,这里 我们可以自己决定 执行哪个挂载钩子上面的函数,执行起来同样也是逆序。

NAME
pthread_cleanup_push, pthread_cleanup_pop - push and pop thread cancellation clean-up handlers

SYNOPSIS
       #include <pthread.h>

// 将函数挂在钩子上。挂载的函数,挂载的函数的参数
       void pthread_cleanup_push(void (*routine)(void *),
                                 void *arg);

//决定当前从钩子上面取下来的函数是否被调用。  参数决定是否调用
       void pthread_cleanup_pop(int execute);

       Compile and link with -pthread.

需要注意的是
pthread_cleanup_push()
pthread_cleanup_pop()

这两个函数是 宏,两个宏是组合使用,必须成对出现,否则会有语法错误。

实验:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

static void cleanup_func(void* p)
{
	puts(p);
}

static void* func(void* p)
{
	puts("Thread is working!");	


	pthread_cleanup_push(cleanup_func,"cleanup1");
	pthread_cleanup_push(cleanup_func,"cleanup2");
	pthread_cleanup_push(cleanup_func,"cleanup3");

	puts("push over!");
	
	pthread_cleanup_pop(1);
	pthread_cleanup_pop(1);
	pthread_cleanup_pop(1);
	
	pthread_exit(NULL);
	//return NULL;
}

int main()
{
	pthread_t tid;
	int err;

	puts("Begin!");

	err = pthread_create(&tid,NULL,func,NULL);	
	if(err)
	{
		fprintf(stderr,"pthread_crearte():%s\n",strerror(err));
		exit(1);
	}

	pthread_join(tid,NULL);
	puts("End!");
	exit(0);

}


mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ gcc pthread_create1.c -lpthread
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ ./a.out 
Begin!
Thread is working!
push over!
cleanup3
cleanup2
cleanup1
End!
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/thread/posix$ 

如果是pthread_cleanup_pop(0); 则不执行,即只弹栈,而不执行对应函数。就算只弹栈,不执行,也一定要写上,有几个push,就一定要有对应的几个 pop,否则会有语法问题。

猜你喜欢

转载自blog.csdn.net/LinuxArmbiggod/article/details/114226562