linux下线程的各个接口,并附带一个线程的小例子

线程

众所周知,进程是资源管理的最小单位,线程是程序执行的最小单位;一个进程下可以有多个线程,线程可以创建线程

pthread_create()

是用于创建一个线程的,创建线程实际上就是确定调用该线程函数的入口点,在线程创建后,就开始运行相关的线程函数

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

thread:指向线程标识符的指针。

attr:设置线程属性,具体内容在下一小节讲解。

start_routine:start_routine 是一个函数指针,指向要运行的线程入口,即线程运行时要执行的函数代码。

arg:运行线程时传入的参数。

• 返回值:若线程创建成功,则返回 0。若线程创建失败,则返回对应的错误代码。

typedef struct
{
   int etachstate; //线程的分离状态
   int schedpolicy; //线程调度策略
   structsched_param schedparam; //线程的调度参数
   int inheritsched; //线程的继承性
   int scope; //线程的作用域
   size_t guardsize; //线程栈末尾的警戒缓冲区大小
   int stackaddr_set; //线程的栈设置
   void* stackaddr; //线程栈的位置
   size_t stacksize; //线程栈的大小
}pthread_attr_t;

pthread_attr_init()

初始化线程对象的属性,函数原型:

int pthread_attr_init(pthread_attr_t *attr);

• attr:指向一个线程属性的指针

• 返回值:若函数调用成功返回 0,否则返回对应的错误代码。

线程的分离状态

在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死

一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。

进程中的线程可以调用 pthread_join() 函数来等待某个线程的终止,获得该线程的终止状态,并收回所占的资源
int pthread_join(pthread_t tid, void **rval_ptr);
pthread_detach() 函数将此线程设置为分离状态,设置为分离状态的
线程在线程结束时,操作系统会自动收回它所占的资源
int pthread_detach(pthread_t tid);

如果一个线程是可结合的,意味着这条线程在退出时不会自动释放自身资源,而会成为僵尸线程,同时意味着该线程的退出值可以被其他线程获取。

如果在创建线程时就知道不需要了解线程的终止状态,那么可以通过修改 pthread_attr_t 结构中

的 detachstate 属性,让线程以分离状态启动

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

获取线程的分离状态:

int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);

• attr:指向一个线程属性的指针。

• detachstate:如果值为 PTHREAD_CREATE_DETACHED,则表示线程是分离状态,如果值为 PTHREAD_CREATE_JOINABLE 则表示线程是结合状态。

线程调度的策略

• 分时调度策略,SCHED_OTHER。这是线程属性的默认值,另外两种调度方式只能用于以超级用户权限运行的进程,因为它们都具备实时调度的功能,但在行为上略有区别。

• 实时调度策略,先进先出方式调度 (SCHED_FIFO)。基于队列的调度程序,对于每个优先级都会使用不同的队列,先进入队列的线程能优先得到运行,线程会一直占用 CPU,直到有更高优先级任务到达或自己主动放弃 CPU 使用权。

• 实时调度策略,时间片轮转方式调度 (SCHED_RR)。与 FIFO 相似,不同的是前者的每个线程都有一个执行时间配额,当采用 SHCED_RR 策略的线程的时间片用完,系统将重新分配时间片,并将该线程置于就绪队列尾,并且切换线程,放在队列尾保证了所有具有相同优先级的 RR 线程的调度公平。

int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int*inheritsched);
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);

线程的优先级

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct schedparam *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct schedparam *param);

线程栈

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);

线程退出

void pthread_exit(void *retval);

例子:

int main()
{
	debug_zlog_init();
	pthread_t thread[2];
	// system("echo 0 > /sys/class/leds/firefly:red:power/brightness");
	// system("echo 0 > /sys/class/leds/firefly:green:user/brightness");


	if (pthread_create(&thread[0], NULL, key_tick, NULL) != 0)
	{
	}
	if (pthread_create(&thread[1], NULL, led, NULL) != 0)
	{
	}
	pthread_join(thread[0], NULL);
	pthread_join(thread[1], NULL);
	
	return 0;
}

例子中的key_tick是一个按键的检测,led是一个切换led灯的颜色的函数,这两个互相不干涉,但是其实在实际的过程中,是会进行相互干涉的。

Guess you like

Origin blog.csdn.net/Wu996/article/details/121329972