创建线程【 GCC编译的时候需要加上选项 -lpthread 添加编译时的静态链接库】
- pthread_t用于表示Thread ID,具体内容根据实现的不同而不同,有可能是一个Structure,因此不能将其看作为整数
- thread具有:ID、栈、信号掩码、等
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg);
int pthread_equal(pthread_t tid1, pthread_t tid2);
pthread _t pthread_self(void);
int pthread_join(pthread_t thread, void **rval_ptr);/*等待给定的线程终止,并挂起本线程*/
void pthread_cancel(pthread_t tid);/*终止其他线程*/
函数说明:
- pthread_create:
- pthread_equal函数用于比较两个pthread_t是否相等
- pthread_self函数用于获得本线程的thread id
终止线程
- exit, _Exit, _exit用于中止当前进程(LWP),而非此类线程
- 中止线程可以有三种方式:在线程函数中return、被统一进程的其他线程cancel、调用pthread_exit()函数
线程同步:
1、互斥锁
#include <pthread.h>
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);//不阻塞,直接返回错误值 EBUSY
int pthread_mutex_unlock(pthread_mutex_t *mutex);
2、条件变量。
- 条件变量需要被mutex被保护
- 用于通知线程条件被满足
- 条件变量是利用线程间共享的全局变量进行同步的一种机制。
#include <pthread.h>
/*动态创建一个条件变量*/
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condxattr_t *restrict attr);
/*静态创建一个条件变量*/
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
/*销毁一个条件变量*/
int pthread_cond_destroy(pthread_cond_t *cond);
/*用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒它。 */
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
/*在给定的时间范围内等待,超时自动返回,返回一个错误值ETIMEOUT*/
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout);
/*通知线程条件满足*/
int pthread_cond_signal(pthread_cond_t *cond);
/*通知一个多个线程*/
int pthread_cond_broadcast(pthread_cond_t *cond);
函数说明:
- pthread_cond_wait必须传入一个已经加锁的互斥锁,如果条件不满足,mutex会被unlock,然后block。等待条件满足后mutex重新被锁定。
- pthread_cond_wait通常被放在一个while循环里面,条件满足后需要重新检查程序是否满足要求。
【pthread_cond_wait放在while里面的原因:signal使得条件满足可能唤醒多个线程,但是也许只有一个线程满足运行条件。】
参考:https://blog.csdn.net/brouce__lee/article/details/81178456
https://www.cnblogs.com/leijiangtao/p/4028338.html【其他原因分析,先unlock 然后 signal 也可能导致条件发生变化】
3、读写锁
- 读写锁的状态: 一个或者多个线程获得读锁,其他线程无法获得写锁;一个线程获得写锁,其他线程无法获得读锁;没有线程获得此读写锁
#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);
条件变量和mutex使用,多线程同步例程:
int num;
static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
void *func(void *);
int main()
{
pthread_t tid[3];
int ret=0,i;
for(i=0;i<3;i++)
if((ret=pthread_create(&tid[i],NULL,func,(void*)i))!=0)
printf("create thread_%c error\n",i+'A');
for(i=0;i<3;i++)
pthread_join(tid[i],NULL);
printf("\n");
return 0;
}
void *func(void *argc)
{
int i;
for(i=0;i<10;i++)
{
pthread_mutex_lock(&mutex);
while(num!=(int)argc)
pthread_cond_wait(&cond,&mutex);
printf("%c\n",num+'A');
num=(num+1)%3;
pthread_mutex_unlock(&mutex);//此处先解锁
pthread_cond_broadcast(&cond);//然后使条件变量成立,可能中间会有并发。
sleep(1);
}
pthread_exit(0);
}