Linux C 线程操作
一、线程的基本概念
1、进程可以分为线程集合和资源集合,线程是一个动态控制对象,它标识进程中的一个控制点,并且执行一系列的指令。资源包含地址空间、打开文件、用户凭证和配额。每个线程有自己的程序计数堆栈和寄存器的值
2.分类:用户态线程:管理上不需要内核参与,统一由用户程序切换
缺点:进程中的一个线程容易占用一个时间片,导致其他线程无法运行
内核态线程:由内核管理,在每个时间片内,内核负责调度进程内线程,一个线程不会独占CPU
缺点:有内核态和用户态的切换,速度变慢,随着CPU数量增多,应用程序运行速度加快
3.线程具有一个ID,一个堆栈,一个执行优先权,以及执行开始的地址
二。创建和结束线程
1.#include<pthread.h>
int pthread_create(pthread_t *thread,pthread_attr_t *attr,void*(*start_routine)(void*),void *arg);
pthread_create(&thread1,NULL,(void *)(&print_message),(void*)msg1);
与创建它的线程同步执行;
start_routine 线程执行函数
arg 函数参数
attr 线程属性 可以为NULL 默认属性
结束:pthread_exit 或者随着函数结束而结束
成功返回0,将线程标识符存入指针thread指向的地址;失败返回非0
2.获取线程ID
pthread_t pthread_self();
printf("Thread ID:%lx ",pthread_self());
3.结束线程
void pthread_exit(void *retval); 将返回一个值到retval
pthread_exit(&retval);
调用成功返回0,失败返回-1
编译:gcc -lpthread -o ex7-1 ex7-1.c
4.挂起线程
int pthread_join(pthread_t th,void ** thread_return);挂起当前线程直至线程终止
thread_return 存放其他进程返回值,每个可连接的进程都会执行一次
成功返回0,将th值保存于thread_return,失败返回非0
pthread_create(&thread1,NULL,(void *)(&print_message),(void*)msg1);
pthread_create(&thread2,NULL,(void *)(&print_message),(void*)msg2);
pthread_join(thread1,&retval);//保证两个进程结束以后退出
pthread_join(thread2,&retval);
5.线程同步
1)互斥锁 :原子性 唯一性 非繁忙等待 一个线程已经锁定互斥锁,另一个线程执行锁操作会被挂起,直至锁打开
操作:int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr *attr)
attr 属性,NULL为默认属性
成功返回0,将创建的锁ID放到mutex中
int pthread_mutex_destroy(pthread_mutex_t *mutex) ;成功返回0,执行失败返回错误编号
int pthread_mutex_lock(pthread_mutex_t *mutex),锁定指定锁,若已被锁定,阻塞调用线程,当函数返回时说明互斥锁已经成功加锁
成功返回0,其他值发生错误
int pthread_mutex_trylock(pthread_mutex_t *mutex),锁定指定锁,若已被锁定,返回错误
成功返回0,失败返回错误
int pthread_mutex_unlock(pthread_mutex_t *mutex), 解锁 成功返回0,其他值以为错误
例。
/*ex7-3*/
#include<stddef.h>
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#define FALSE 0
#define TRUE 1
void readfun();
void writefun();
char buffer[256];
int buffer_has_item=0;
int retflag=FALSE;
pthread_mutex_t mutex;
int main()
{
pthread_t reader;
pthread_mutex_init(&mutex,NULL);
pthread_create(&reader,NULL,(void *)readfun,NULL);
writefun();
}
void readfun()
{
while(1)
{
if(retflag)
return;
pthread_mutex_lock(&mutex);
if(buffer_has_item==1)
{
printf("%s",buffer);
buffer_has_item=0;
}
pthread_mutex_unlock(&mutex);
}
}
void writefun()
{
int i=0;
while(1)
{
if(i==10)
{
retflag=TRUE;
return;
}
pthread_mutex_lock(&mutex);
if(buffer_has_item==0)
{
sprintf(buffer,"This is %d\n",i++);
buffer_has_item=1;
}
pthread_mutex_unlock(&mutex);
}
}
2)条件变量
1.int pthread_cond_init(pthread_cond_t *cond,pthread_cond_atrr *atrr); atrr 设置属性 NULL默认
创建chengg返回0,条件变量ID 放在参数cond中,返回其他值意味着出错
2.int phread_cond_destroy(pthread_cond_t *cond) 清除cond指向条件变量的状态,但是存储空间不放
成功返回0,返回其他值意味着出错
3.int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex) 释放mutex锁,阻塞调用cond指向条件变量的线程
成功返回0,返回其他值意味着出错
4..int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex_t *mutex,struct timespec *abstime) 释放mutex锁,阻塞调用cond指向条件变量的线程直至条件变量获得信号或者经过abstime时间
成功返回0,超过时间返回ETIMEOUT,返回其他值意味着出错
5.phread_cond_signal
int phread_cond_signal(pthread_cond_t *cond)使参数cond指向的条件变量阻塞线程退出阻塞状态
成功返回0,返回其他值意味着出错
6.int phread_cond_broadcast(pthread_cond_t *cond)使所有参数cond指向的条件变量阻塞线程退出阻塞状态
7.当前线程调用线程取消另一个线程
int pthread_cancel(pthread_t thread); 成功返回0,失败返回错误代码
int pthread_setcancelstate(int state,int *oldstate);设置调用函数线程自身的状态,设置成功返回0,失败返回错误
int pthread_setcanceltype(int type,int *oldtype);设置对取消的响应方式,PTHREAD_CANCEL_ASYNCHRONOUS 立刻取消 PTHREAD_CANCEL_DEFERRED 延迟取消至取消点,成功返回0,失败返回错误代码
void pthread_testcancel();设置取消点;若是延迟取消请求挂起,函数取消当前进程
8.线程清理工作
void pthread_cleanup_push(void(*rutine)(void*),void *argc)
将程序rutine和arg一起压入当前线程的cleanup处理栈,当当前线程调用pthread_exit或者通过pthread_cancel终止执行时,堆栈中处理程序将按照压栈时反向调用
执行失败,没有返回任何错误报告
void pthread_cleanup_pop(int execute) 从线程的cleanup处理程序堆栈中弹出最上面的一个处理程序执行它
如果执行失败,不会返回错误报告
9.线程特定数据处理函数
1)int pthread_key_create(pthreda_key_t *key,void(*dest_routine(void*)))
创建一个进程中所有可以见得关键字, ,当创建一个关键字时,进程中所有线程的这个关键字都是NULL,创建一个线程时,线程所有的关键字都是null
成功返回0,key中保存新创建的关键字,其他值错误
2)int phread_key_delete(phread_key_t key) 删除key指定的关键字,成功返回0,其他值,意味着错误
3)int phread_setspecific(phtead_key_t key,void *pointer)指定由pointer指向的指针指向参数key关键字 成功返回0,其他意味着错误
4)void *phread_getspecific(phtead_key_t key)获取 phread_setspecific指定指针 成功返回0,其他返回意味着错误
5)void * pthread_once_t once_control(PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *once_control,void(*init_routine)(void));
保证某些初始化代码只执行一次,总是返回0
9.线程属性
1、初始化一个线程对象的属性
int pthread_attr_init(pthread_attr_t *attr);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
说 明:Posix线程中的线程属性pthread_attr_t主要包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。
pthread_attr_init实现时为属性对象分配了动态内存空间。
头文件:#include <pthread.h>
2、销毁一个线程属性对象
int pthread_attr_destroy(pthread_attr_t *attr);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
说 明:经pthread_attr_destroy去除初始化之后的pthread_attr_t结构被pthread_create函数调用,将会导致其返回错误。
头文件:#include <pthread.h>
3、获取线程的栈保护区大小
int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
guardsize 返回获取的栈保护区大小
说 明:获取线程的栈保护区大小
头文件:#include <pthread.h>
4、设置线程的栈保护区大小
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
guardsize 线程的栈保护区大小
说 明:参数提供了对栈指针溢出的保护。
默认为系统页大小
如果设置为0表示没有保护区。
大于0,则会为每个使用 attr 创建的线程提供大小至少为 guardsize 字节的溢出保护区
头文件:#include <pthread.h>
5、获取线程分离状态属性
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
detachstate 保存返回的分离状态属性默认为 PTHREAD_CREATE_JOINABLE
说 明:获取线程分离状态属性,脱离状态下的新城资源在线程结束后就立即释放,而且不能用pthread_join函数来同步终止
头文件:#include <pthread.h>
6、修改线程分离状态属性
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
detachstat 有两个取值
PTHREAD_CREATE_DETACHED(分离)
PTHREAD_CREATE_JOINABLE(非分离)
说 明:Posix线程中的线程属性pthread_attr_t主要包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。
头文件:#include <pthread.h>
9、获取线程的作用域
int pthread_attr_getscope(pthread_attr_t *attr, int *scope);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
scope 返回线程的作用域,可能为PTHREAD_SCOPE_PROCESS 或者是PTHREAD_SCOPE_SYSTEM(默认)
说 明:指定了作用域也就指定了线程与谁竞争资源
头文件:#include <pthread.h>
10、设置线程的作用域 int pthread_attr_setscope(pthread_attr_t *attr, int scope); 返回值:若是成功返回0,否则返回错误的编号 形 参: attr 指向一个线程属性的指针 guardsize 线程的作用域,可以取如下值 PTHREAD_SCOPE_SYSTEM 与系统中所有进程中线程竞争 PTHREAD_SCOPE_PROCESS 与当前进程中的其他线程竞争 说 明:指定了作用域也就指定了线程与谁竞争资源 头文件:#include <pthread.h>
17、获取线程的调度策略
int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
policy 返回线程的调度策略
说 明:获取线程的调度策略
头文件:#include <pthread.h>
18、设置线程的调度策略
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
policy 线程的调度策略,有如下三种:
SCHED_FIFO 先入先出策略
SCHED_RR 轮转调度,类似于 FIFO,但加上了时间轮片算法
SCHED_OTHER 系统默认策略
说 明:设置线程的调度策略
头文件:#include <pthread.h>
21、获取线程是否继承调度属性
int pthread_attr_getinheritsched(pthread_attr_t *attr, int *inheritsched);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
inheritsched 返回继承调度属性的设置
说 明:获取线程是否继承调度属性
头文件:#include <pthread.h>
22、设置线程是否继承调度属性
int pthread_attr_getinheritsched(pthread_attr_t *attr, int *inheritsched);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
guardsize 设置线程是否继承调度属性
PTHREAD_INHERIT_SCHED:调度属性将继承于正创建的线程
attr中的设置将被忽略
PTHREAD_EXPLICIT_SCHED 调度属性将被设置为attr中指定的属性值
说 明:
头文件:#include <pthread.h>
19、获取线程的调度参数
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
param 返回获取的调度参数,该结构仅有一个从参数,如下
struct sched_param
{
int sched_priority; /* Scheduling priority */
};
说 明:获取线程的调度参数
头文件:#include <pthread.h>
20、设置线程的调度参数
int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param *param);
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
param 要设置的调度参数
说 明:设置线程的调度参数
头文件:#include <pthread.h>

浙公网安备 33010602011771号