线 程 的 传 参
1、pthread_create(tid,NULL,fun,arg); ===>arg 回调函数参数
1.1 向子线程中传入数字
1.2 向子线程中传入字符串
1.3 向子线程中传入结构体
练习:设计一个多线程函数,并向其中送入一个结构体变量
在线程中打印输出结构体变量的所有成员变量值。
2 、多线程的互斥 ===》互斥锁 ====》pthread_mutex_t 类型的锁
目的:保护临界资源的排他性访问。
操作流程:
0:定义一个全局的互斥锁变量:
静态变量: pthread_mutex_t mutex;
动态变量: pthread_mutex_t mutex = malloc();
free();
1、初始化互斥锁 pthread_mutex_init()
原型:int pthread_mutex_init(pthread_mutex_t * mutex const pthread_mutexattr_t * attr);
功能:该函数用于线程中初始化设置一个已经定义的互斥锁。
一般用于线程的创建者执行。
参数: mutex 已经定义的互斥锁
attr 互斥锁的属性,默认属性是NULL;
返回值:成功 0
失败 -1;
2、加锁 pthread_mutex_lock()
原型:int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:用来控制临界资源的访问,如果该代码执行
则在解锁之前,该代码之后的所有语句都执行原子操作。
参数: mutex 执行过程中的互斥锁
返回值:成功 0
失败 -1
3、解锁 pthread_mutex_unlock();
原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:该函数用于之前加锁的进程执行解锁动作。
参数: mutex 要执行解锁任务的互斥锁。
返回值:成功 0
失败 -1;
4、销毁锁 pthread_mutex_destroy();
原型 :int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:用来销毁不再使用的互斥锁,如果其他进程要用就必须重新
初始化并加解锁。
参数: mutex 要操作的互斥锁
返回值:成功 0
失败 -1;
问题:
1、该部分代码要验证什么问题?
2、代码中的 _LOCK_ 是什么含义,有什么作用。
3、该部分代码执行过程中有几个线程
4、代码执行的结果是什么? 能否改进。
练习:
设计一个多线程任务,尝试不同的线程同时进行文件写操作。
要求每个线程写入的信息不能交叉不能覆盖。
建议:使用互斥锁实现。
3、多线程的同步操作:===》信号量 ===>二值信号量
头文件: semaphore.h
操作流程: 信号量的定义 ===》定义变量
信号量的初始化 ===》sem_init
信号量的PV操作 ===》sem_wait ==>p sem_post ==>v
p操作: 申请信号量资源
v操作: 释放信号量资源
信号量的销毁 ===》sem_destroy
定义变量: sem_t sem ==>用sem_t 类型来定义一个信号量
可以是全局变量也可以是堆区变量
信号量的初始化: sem_init()
原型:int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:将已经申请的信号量做初始化赋值
参数:sem 信号量
pshared 使用范围: 0 线程间使用 非0 进程间使用
value 信号量的初始值。如果是0 则进程在申请资源时候阻塞
1 则进程可以申请资源。
返回值:成功 0
失败 -1;
信号量的PV操作
1、p操作:int sem_wait(sem_t *sem);
功能:该函数用于线程间测试信号量资源是否可以使用。
如果sem是0 ,则该线程阻塞等待。
如果sem是1,则线程继续运行,
同时sem值减1==》sem = sem-1;
参数:sem 要检测的信号量
返回值:成功 0
失败 -1;
2、v操作:int sem_post(sem_t *sem);
功能:该函数用于线程使用完毕信号量并释放资源。
该函数不会阻塞线程,默认会进行sem= sem+1;
参数:sem 要操作的信号量
返回值:成功 0
失败 -1;
信号量的销毁:int sem_destroy(sem_t *sem);
功能:在信号量使用完毕后,对该资源回收。
参数:sem 要回收的信号量
返回值:成功 0
失败 -1;
信号量的当前值查询: int sem_getvalue(sem_t *sem, int *sval);
功能:获取当前信号量的值
参数:sem要获取当前值的信号量
sval 要获取的值的内存空间,需要实现定义变量。
返回值:成功 0
失败 -1;
练习:
使用以上信号量的知识,设计一个多线程程序,完成如下功能:
1、尽可能少的申请线程
2、一个线程动态获取用户输入
3、另一个线程将用户输入的字符,统计并将个数打印输出。
作业:
用多线程实现火车票售票系统,要求至少有两个售票窗口。
从以上窗口中均匀的卖出100张火车票,每个窗口不能重复卖票。
./a.out
window 1 sale 1
window 2 sale 2
......