郑州租赁房网站建设,网站首页模板图片,时尚杂志网站设计分析,推广普通话手抄报目录
一#xff0c;线程函数
1.获取当前线程ID
2.创建线程
3.退出线程
4.阻塞线程
5.分离线程
6.取消线程
7.线程比较
8.测试代码#xff08;线程函数总结#xff09;
二#xff0c;线程同步
1.互斥锁
2.读写锁
3.条件变量
4.信号量 一#xff0c;线程函数 …目录
一线程函数
1.获取当前线程ID
2.创建线程
3.退出线程
4.阻塞线程
5.分离线程
6.取消线程
7.线程比较
8.测试代码线程函数总结
二线程同步
1.互斥锁
2.读写锁
3.条件变量
4.信号量 一线程函数
参考文章 线程 | 爱编程的大丙man command //Linux终端命令 # 查阅 command 命令的使用手册包含了绝大部分的命令和函数的详细使用说明 获取当前线程IDpthread_t pthread_self(void);创建线程int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *),void *arg);退出线程void pthread_exit(void *retval);阻塞线程int pthread_join(pthread_t thread, void **retval);分离线程int pthread_detach(pthread_t thread);取消线程(杀死线程)int pthread_cancel(pthread_t thread);线程比较int pthread_equal(pthread_t t1, pthread_t t2);
1.获取当前线程ID
//获取当前线程的线程IDID类型为pthread_t它是一个无符号长整型数
pthread_t pthread_self(void);
返回值 永远返回成功返回被调用者的线程ID2.创建线程
//在进程中调用线程创建函数来创建一个子线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *),void *arg);
参数介绍thread输出参数线程创建成功会将线程ID写入到该指针所指向的内存中attr线程的属性一般设置为NULL即线程的创建使用默认属性start_routine函数指针子线程的业务处理函数即传入的函数指针会在该子线程中执行arg函数参数和start_routine指针指向的函数参数匹对即该参数是传递给start_routine指针所指向的函数
返回值创建成功返回0创建失败返回一个错误号并且*thread值未定义
3.退出线程
//线程退出不会影响到其它线程的正常运行子线程或主线程都可以调用
void pthread_exit(void *retval);
参数被调用线程退出时其它线程可通过retval获取线程退出时携带的数据。不需要数据可以指定为NULL4.阻塞线程
//函数被调用一次只会回收一个子线程如果有多个线程需要循环传入线程ID进行回收
int pthread_join(pthread_t thread, void **retval);
参数介绍 thread要被阻塞的线程ID指定的线程必须是可被阻塞的retval所指向一级指针的地址是一个输出参数该地址中存储了pthread_exit()传出的数据不需要数据可以指定为NULL返回值成功返回0失败返回一个错误码5.分离线程
/*
1.传入分离子线程的线程ID便会与主线程分离当子线程退出的时候其占用的资源就会被系统的其它进程接管并回收。
2.不可对同一线程重复分离不然会出现未定义行为
*/
int pthread_detach(pthread_t thread); 6.取消线程
int pthread_cancel(pthread_t thread); 7.线程比较
int pthread_equal(pthread_t t1, pthread_t t2); 8.测试代码线程函数总结
#include cstdio
#include stdlib.h
#include unistd.h
#include pthread.h//子线程处理代码
void* threadFun(void *_arg){printf(子线程线程ID%ld 传入参数值%ld\n, pthread_self(),*(int*)_arg);for (int i 0; i 5; i){sleep(1);printf(subThread-i: %d\n, i);if (i 3) {int* val (int*)malloc(sizeof(int));*val i;pthread_exit(val); //子线程退出携带的数据val可以被主线程中调用pthread_join获取}}return nullptr;
}int main()
{printf(主线程线程ID%ld\n, pthread_self());for (int i 0; i 5; i){sleep(1);printf(main-i: %d\n, i);}pthread_t tid; //创建一个子线程int thread_arg 1008; //传给threadFun()线程工作函数的参数int flag pthread_create(tid, nullptr, threadFun, (void*)thread_arg);if (flag 0){printf(子线程创建成功线程ID%ld 传入threadFun()线程函数的参数值%d\n, tid,thread_arg);}//pthread_detach(tid); /** 线程分离之后在主线程使用pthread_join()就会报段错误核心已转储* 因为子线程退出时其占用的内核资源被系统其它进程回收了然而你又对它进行操作。*/void *subTd_retval nullptr;pthread_join(tid, subTd_retval); //阻塞子线程并获取子线程退出时的数据printf(子线程 %ld 返回的数据%ld\n, tid, *(int*)subTd_retval);pthread_detach(tid); //这里让子线程与主线程分离pthread_exit(nullptr); //让主线程自己退出return 0;
} 二线程同步 参考文章 线程同步 | 爱编程的大丙 1.当多个线程对共享资源多个线程共同访问的变量进行访问的时候就会出现数据混乱的问题所以就需要进行线程同步所谓的线程同步实际上是各线程按先后顺序依次对共享资源进行访问而不是同时进行的其实也就是让各线程去抢占CPU时间片抢到就访问数据没抢到就挂起这之间会涉及到上下文的切换。虽然降低了运行效率但提高了数据访问的安全性这是值得的。 2.线程同步有四种方式互斥锁读写时条件变量信号量。 3.互斥锁读写时条件变量在头文件pthread中信号量在头文件semaphore中。 1.互斥锁
//每一个共享资源对应一把锁锁的个数和线程的个数无关
pthread_mutex_t mutex;//初始化互斥锁被restrict修饰的指针可以访问指向的内存地址
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);//释放互斥锁资源
int pthread_mutex_destroy(pthread_mutex_t *mutex);//修改互斥锁状态对传入的互斥锁进行加锁
int pthread_mutex_lock(pthread_mutex_t *mutex);//对传入的互斥锁进行尝试加锁
int pthread_mutex_trylock(pthread_mutex_t *mutex);//对传入的互斥锁进行解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);2.读写锁
//读写锁是互斥锁的升级版读锁是共享的写锁是互斥独占的。写锁优先级比读锁高
pthread_rwlock_t rwlock;//初始化读写锁attr默认为NULL就行
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);//释放读写锁占用的系统资源
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);//修改读写锁状态锁定读操作,读锁可以重复锁
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);//对传入的读写锁进行尝试加读锁
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);//对传入的读写锁进行加写锁
int pthread_rwlock_wdlock(pthread_rwlock_t *rwlock);//对传入的读写锁进行尝试加写锁
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
3.条件变量
条件变量不是处理线程同步的而是进行线程的阻塞。多线程实现线程同步需要配合互斥锁来使用。
//条件变量类型的定义
pthread_cond_t cond;//初始化条件变量一般attr默认为NULL就行
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_cond_t *restrict attr);//释放条件变量资源
int pthread_cond_destroy(pthread_cond_t *cond);//线程阻塞函数哪个线程调用这个函数就会阻塞哪个线程
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);//唤醒在条件变量上阻塞的线程(至少一个)
int pthread_cond_signal(pthread_cond_t *cond);//唤醒在条件变量阻塞的全部线程
int pthread_cond_broadcast(pthread_cond_t *cond);
4.信号量 信号量 主要是阻塞线程不能保证线程安全如果要保证线程安全需要信号量和互斥锁一起使用
1.定义信号量变量
sem_t sem;
2.初始化信号量
int sem_init(sem_t *sem, int pshared, unsigned int value);
参数 sem信号量变量地址pshared0-线程同步!0-进程同步value初始化信号量*sem拥有的资源数(0)为0就会阻塞线程3.销毁信号量
int sem_destroy(sem_t *sem); 4.锁住一个信号量资源资源数0时会阻塞线程
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); 5.释放一个信号量资源
int sem_post(sem_t *sem); 6.获取信号量的资源数
//sval是输出参数可以通过sval获取信号量sem中拥有的资源数量
int sem_getvalue(sem_t *sem, int *sval);