DAY 5
线程进程基本操作
一、创建线程 pthread_create
int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
第一个参数为指向线程标识符的指针,也就是线程对象的指针
第二个参数用来设置线程属性。
第三个参数是线程运行函数的地址,通俗理解线程要执行函数(线程做的事情的)指针。
一般这个函数执行时间比较长(有while循环),做的事情比较多。如果单次动作(执行时间比较短),也就无需多线程执行了。
最后一个参数是线程要运行函数的参数。
线程的默认堆栈大小是1MB,就是说,系统每创建一个线程就要至少提供1MB的内存,那么,创建线程失败,极有可能就是内存不够用了。
pthread_create会导致内存泄露! pthread_create创建的线程结束后,系统并未回收其资源,从而导致了泄露。
1.使用pthread_join()函数回收相关内存区域。
int pthread_detach(pthread_t thread);将已经运行中的线程设定为分离状态;
pthread_t tid;void* state;pthread_create(&tid, NULL, test, NULL);pthread_join(tid, &state);
pthread_t tid;
void* state;
pthread_create(&tid, NULL, test, NULL);
pthread_join(tid, &state);
一、什么是互斥锁
保证线程安全的一种锁机制,在同一时刻,只允许一个执行流去访问临界资源。
二、为什么需要互斥锁
由于CPU进行程序处理的时候并不会一次性将一个程序执行完毕,而是执行一个时间片之后会切换另外一个程序,这种方式也称位CPU的分时机制。正因为这种机制不能保证每一次的执行流都是原子操作,会导致程序出现二义性;互斥锁就是为了解决当多个执行流去访问共享资源的时候出现的二义性问题。
三、互斥锁的原理
本质上可以认为是一个计数器,在互斥锁的内部有一个计数器,实际上就是一个互斥量;计数器的取值只能是0或1,当一个线程去获取临界资源的时候,首先去获取互斥锁,当计数器的值为1的时候,表示当前的锁资源可以获取,当获取成功之后计数器的值就变成0,也就可以对临界资源进行访问修改;当计数器的值为0的时候,表示当前的锁资源不可以获取,就是没有获取到互斥锁,也就不可以访问临界资源,执行流就行阻塞等待。
四、互斥锁的相关接口
//初始化互斥锁
int pthread_mutex_init(pthread_mutex_t* mutex,pthread_mutexattr_t* attr)
//pthread_mutex_t* mutex 互斥锁变量类型
//pthread_mutexattr_t* attr 互斥锁属性, 一般传递NULL
//销毁互斥锁
pthread_mutex_destroy(pthread_mutex_t* mutex)
//加锁
int pthread_mutex_lock(pthread_mutex_t* mutex)
//mutex:传入互斥锁变量的地址
int pthread_mutex_trylock(pthread_mutex_t* mutex)
//该接口是非阻塞加锁接口,一般需要搭配循环来使用
int pthread_mutex_timedlock(pthread_mutex_t* mutex, const struct timespec* abs_timeout)
//带有超时时间的加锁接口
//解锁
int pthread_mutex_unlock(pthread_mutex_t* mutex)
线程同步之信号量
函数原型 :int sem_init(sem_t *sem, int pshared, unsigned int value);
参数解释 :
sem :指向信号量对象
pshared : 指明信号量的类型。当为0时,用于进程;当为0时,用于线程。
value : 指定信号量值的大小
返回值:成功返回0,失败时返回-1,并设置errno。
作用:创建信号量,并为信号量值赋初值。
函数原型:int sem_post(sem_t *sem);
参数解释 :
sem :指向信号量对象
返回值:成功返回0,失败时返回-1,并设置errno。
作用: 以原子操作的方式为将信号量增加1
函数原型:sem_wait(sem_t *sem);
参数解释 :
sem :指向信号量对象
返回值:成功返回0,失败时返回-1,并设置errno
作用: 以阻塞的方式等待信号量,当信号量的值大于零时,执行该函数信号量减一,当信号量为零时,调用该函数的线程将会阻塞。
函数原型:sem_destroy(sem_t *sem);
参数解释 :
sem :指向信号量对象
返回值:成功返回0,失败时返回-1,并设置errno
作用: 清理信号量占有的资源,当调用该函数,而有线程等待此信号量时,将会返回错信息。