linux线程相关函数

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

#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.

// 功能:  创建一个新线程,执行 start_routine 函数,
//         传递 arg 作为参数,使用 attr 设置新线程的属性
// 参数:  thread        线程 ID 号
//         attr          新线程的属性,使用默认属性则可以为 NULL
//         start_routine 线程要执行的任何的入口函数
//         arg           传递给新线程的参数
// 返回值:成功返回 0,失败返回错误号
// 注:    线程结束的情况:
//         1. 线程中调用了 pthread_exit(3),同一个进程中的其它线程
//            可以使用 pthread_join(3) 获取返回值。
//         2. 从 start_routine() 中返回。
//         3. 被 pthread_cancel(3) 取消。
//         4. 进程中的任何线程调用了 exit(3),或主线程返回,
//            进程结束,则线程也结束

       * It  calls  pthread_exit(3),  specifying  an exit status value that is
         available  to  another  thread  in  the  same  process   that   calls
         pthread_join(3).

       * It  returns  from  start_routine().   This  is  equivalent to calling
         pthread_exit(3) with the value supplied in the return statement.

       * It is canceled (see pthread_cancel(3)).

       * Any of the threads in the process calls exit(3), or the  main  thread
         performs  a  return  from main().  This causes the termination of all
         threads in the process.


2.0 pthread_t pthread_self(void)

#include <pthread.h>

pthread_t pthread_self(void);

Compile and link with -pthread.

// 功能:  获取调用线程的 ID,与 pthread_create 的 *thread 参数同值
// 参数:  无
// 返回值:线程 ID
NAME
       pthread_self - obtain ID of the calling thread

SYNOPSIS
       #include <pthread.h>

       pthread_t   pthread_self(void);

       Compile and link with -pthread.

DESCRIPTION
       The pthread_self() function returns the ID of the calling thread.  This
       is the same value that is returned in *thread in the  pthread_create(3)
       call that created this thread.

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

ERRORS
       This function always succeeds.

 3.0 void pthread_exit(void *retval)

Compile and link with -pthread.

// 功能:  结束调用线程
// 参数:  retval 返回值
// 返回值:无

DESCRIPTION
       The pthread_exit() function terminates the calling thread and returns a
       value via retval that (if the  thread  is  joinable)  is  available  to
       another thread in the same process that calls pthread_join(3).

       Any  clean-up handlers established by pthread_cleanup_push(3) that have
       not yet been popped, are popped (in the reverse of the order  in  which
       they  were pushed) and executed.  If the thread has any thread-specific
       data, then, after the clean-up handlers have been executed, the  corre‐
       sponding destructor functions are called, in an unspecified order.

       When a thread terminates, process-shared resources (e.g., mutexes, con‐
       dition variables, semaphores, and file descriptors) are  not  released,
       and functions registered using atexit(3) are not called.

       After  the  last thread in a process terminates, the process terminates
       as by calling exit(3) with an exit status of zero; thus, process-shared
       resources  are  released  and  functions registered using atexit(3) are
       called.

 4.0 int pthread_detach(pthread_t thread);5.0 int pthread_join(pthread_t thread, void **retval);

前言:
1.linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在
线程函数退出时   或  pthread_exit时自动会被释放
2.unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join.
3.其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦。

 

int pthread_detach(pthread_t thread);

Compile and link with -pthread.

// 功能:  分离线程 thread
//         当分离的线程结束后,会自动释放资源,而无需其它线程回收
// 参数:  thread 要分离的线程 ID
// 返回值:成功返回 0,失败返回错误号



#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);

Compile and link with -pthread.

// 功能:  等待线程 thread 结束。
//         如果线程 thread 已结束,则立即返回。
//         线程 thread 必须是可等待的。
//         多个线程同时等待同一个线程,结果未定义。
//         如果调用 pthread_join() 的线程被取消,则线程 thread 依然
//         保持可等待。
// 参数:  thread 要等待的线程
//         retval 结束线程的返回值。如果非 NULL,线程的退出状态会保存
//                在 *retval 中;如果线程 thread 已被取消,则会保存
//                PTHREAD_CANCELED 在 *retval 中
// 返回值:成功返回 0,失败返回错误号

 6.0 int pthread_cancel(pthread_t thread)见博客

#include <pthread.h>

int pthread_cancel(pthread_t thread);

Compile and link with -pthread.

// 功能:  请求取消线程 thread
//         线程能否及何时取消,取决于线程属性中的 state 和 type,
//         pthread_setcancelstate() 函数可使能或禁用,
//         pthread_setcanceltype() 函数可设置何时取消(异步和延迟)。
//         执行取消的步骤:
//         1. 按 pthread_cleanup_push(3) 相反的顺序调用清除函数。
//         2. 线程特定的数据自毁装置被调用。
//         3. 线程结束
//         以上取消步骤异步于 pthread_cancel() 函数
// 参数:  thread 要取消的线程
// 返回值:成功返回 0,失败返回非0的错误号

7.0 清理线程

void *start_routine(void *arg)
{
	int i = 0;

	// 入栈和出栈必须成对出现
	pthread_cleanup_push(routine1, (void *) 1);
	pthread_cleanup_push(routine2, (void *) 2);
	pthread_cleanup_push(routine3, (void *) 3);
	pthread_cleanup_push(routine4, (void *) 4);

	printf("---------------\n");
	// 退出时会自动按入栈的相反顺序调用清理函数
	//pthread_exit((void *) 1);	
	// exit(3) 退出时不会自动调用清理函数
	//exit(1);
	// 取消自己时会自动按入栈的相反顺序调用清理函数
	pthread_cancel(pthread_self());
	
	// 手动出栈
	pthread_cleanup_pop(1);   // 参数 非0 表示出栈并执行
	pthread_cleanup_pop(0);   // 参数 0 表示只出栈,不执行
	pthread_cleanup_pop(1);
	pthread_cleanup_pop(1);
	
	printf("===============\n");

	return NULL;
}

8.0 线程调度

// 初始化默认的线程属性到 attr 中
int pthread_attr_init(pthread_attr_t *attr);

// 销毁 attr 中的线性属性
int pthread_attr_destroy(pthread_attr_t *attr);

Compile and link with -pthread.

// 以上函数成功返回 0,失败返回非 0 的错误号

// 获取/设置线程分离状态
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(const pthread_attr_t *attr, 
			int *detachstate);
// 状态取值:
// PTHREAD_CREATE_DETACHED  分离的
// PTHREAD_CREATE_JOINABLE  可等待的(默认的)

// 获取/设置竞争调度范围
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);

// 调度范围取值:
// PTHREAD_SCOPE_SYSTEM  系统级,Linux 只支持系统级
// PTHREAD_SCOPE_PROCESS 进程级
// 注意,必须使用 pthread_attr_setinheritsched(3) 函数设置继承属性为
// PTHREAD_EXPLICIT_SCHED 才能设置调度范围

// 获取/设置调度策略
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
// 调度策略取值:
// SCHED_FIFO  先进先出调度策略。具有最高优先级的,等待最长时间
//             的线程先调度。实时策略,支持优先级抢占
// SCHED_RR    在FIFO的基础上加入了时间片轮询。实时策略,支持优先级抢占
// SCHED_OTHER 系统默认调度策略,竞争的线程按优先级得到时间片。
//             非实时策略,不支持优先级抢占(默认策略)
// 注意,必须使用 pthread_attr_setinheritsched(3) 函数设置继承属性为
// PTHREAD_EXPLICIT_SCHED 才能设置调度范围

// 获取/设置调度优先级
int pthread_attr_setschedparam(pthread_attr_t *attr,
			const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr,
			struct sched_param *param);
struct sched_param {
	int sched_priority;     /* Scheduling priority */
};
// 优先级数值越大,级别越高
// SCHED_FIFO 和 SCHED_RR 策略下静态优先级为 1 - 99
// 其它策略下优先级为 0
// 注意,必须使用 pthread_attr_setinheritsched(3) 函数设置继承属性为
// PTHREAD_EXPLICIT_SCHED 才能设置调度范围

猜你喜欢

转载自blog.csdn.net/h490516509/article/details/85253148