线程
线程
线程创建
1 2 3 4 5 6 7 8 9 10 11 12
| #include<pthread.h> int pthread_creat( pthread_t *thread, pthread_attr_t *attr, void *(*func)(void*), void *arg )
int pthread_join( pthread_t pthread, void* retval )
|
在linux中使用pthread.h头文件需要连接lpthread库
线程池
组成成分
- 线程池管理器
- 工作线程
- 任务接口
- 任务队列
工作流程
1 2 3 4 5 6 7
| 1. 初始化线程池 2. 堵塞任务线程 2. 将任务添加进人物队列 3. 判断是否有空闲线程 4. 唤醒线程 5. 完成任务 6. 重新堵塞线程
|
常见线程池
优点
1 2 3
| 1. 控制线程产生数量,控制线程对象的内存消耗 2. 降低系统开销和资源消耗 3. 提高系统响应速度
|
通信
线程
进程
- 命名通道 1. 通道是一个队列而不是常规文件 2. 其读和写是原子操作
- 共享内存 1. 共享内存段不依赖于进程存在 2. 共享内存段的名字叫关键字 3. 关键字是一个整型数 4. 共享内存段有自己的拥有者己权限位 5. 进程可以连接共享内存段,并获得指针
- 文件锁
- 信号量
- 相关函数 1. select、poll 2. mkfio 3. shmget、shmat、shmctl、shmdt(共享内存) 4.semget、semctl、semop
同步
互斥量
1 2 3 4 5 6 7 8
| #include <pthread.h> int pthread_mutex_lock( pthread_mutex_t *mutex )
int pthread_mutex_unlock( pthread_mutex_t *mutex, )
|
条件变量
1 2 3 4 5 6 7 8
| #include <pthread.h> int pthread_cond_wait( pthread_cond_t *cond, pthread_mutex_t *mutex, )
int pthread_cond_signal( pthread_cond_t *cond)
|
pthread_cond函数总是和互斥锁在一起使用。此函数先自动释放指定的锁,然后等待条件变量的变化。如果在调用此函数之前,互斥量mutex并没有被锁住,函数执行的结果是不确定的。在返回原调用函数之前,此函数自动将指定的互斥量重新锁住。
信号量
1 2 3 4 5 6
| #include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int value); P int sem_wait(sem_t *sem); V int sem_post(sem_t *sem);
|
读写锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <pthread.h> 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_wrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
|
安全
在多线程程序中,很有可能会将同一个文件描述符传递给两个不同的线程。即传递给它们的两个值指向同一个文件描述符。显然如果一个线程中的函数关闭了这个文件,此文件描述符对此进程中的任何线程来说都已经被关闭。
fork创建了一个新的进程,并把原调用进程的数据和代码复制给这个新的进程。如果线程中的某函数调用了 fork,只有调用fork的线程在新的进程中运行
总结
-[ ] select和epoll