1 新建线程pthread_create(pthread_t *__restrict __newthread,
const pthread_attr_t *__restrict __attr,
void *(*__start_routine) (void *),
void *__restrict __arg)
参数1是pthread_t类型的指针,指针对应的实体应该提前定义
参数2是线程属性的定义
参数3是新线程的入口函数指针,入口函数必须是一个入参void*,返回值void*的函数
参数4是入口函数的void*,你可以将任意的内存转成void*给线程,线程内部转换回来之后就能使用这些参数了
2 阻塞等待其他线程int pthread_join (pthread_t __th, void **__thread_return);
参数1 th是在pthread_create中传入的线程id
参数2 return是线程退出时返回的void*的指针
一个获取线程退出的返回值的例子:
pthread_t thread1;
void* returnValue;
returnValue = new int();
pthread_create(&thread1, NULL, thread1Entry, NULL);
pthread_join(thread1, &returnValue);
returnValue只想的内存几保存了线程退出的返回值
3 分离线程int pthread_detach (pthread_t __th):被分离的线程不能被join,分离的线程在线程结束后会自行销毁私有资源,而join的线程在调用join之后才会销毁私有资源,线程的私有资源包括堆栈信息,寄存器信息等
4 初始化互斥锁pthread_mutex_init(pthread_mutex_t *__mutex,
const pthread_mutexattr_t *__mutexattr)
参数1是要初始化的互斥锁
参数2是锁的属性
需要注意的是,锁的初始化一定要在进入线程之前,假设多个线程运行同一段代码,在线程内部初始化锁,但是他们初始化的实际上不是一个锁,不能起到互斥的作用
pthread_mutex_lock (pthread_mutex_t *__mutex)加锁
pthread_mutex_unlock (pthread_mutex_t *__mutex)解锁
一个简单的死锁实例
void* thread2Entry(void* arg)
{
printThread("thread2");
pthread_mutex_lock(&mutex1);
sleep(10);
pthread_mutex_lock(&mutex2);
for(int i = 0; i< 100; i++)
{
printf("i is %d\n", i);
}
pthread_mutex_unlock(&mutex1);
pthread_mutex_unlock(&mutex2);
return (void*)203;
}
void* thread3Entry(void* arg)
{
printThread("thread3");
pthread_mutex_lock(&mutex2);
sleep(10);
pthread_mutex_lock(&mutex1);
printThread("thread1");
for(int i = 0; i< 100; i++)
{
printf("i is %d\n", i);
}
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
return (void*)203;
}
由于线程1和线程2加锁和解锁的顺序相反,两种都试图获取对方的锁,从而导致死锁
信号量:
int sem_init(sem_t *sem, int pshared, unsigned int value);
,其中sem
是要初始化的信号量,pshared
表示此信号量是在进程间共享还是线程间共享,value是信号量的初始值,
int sem_destroy(sem_t *sem);
,其中sem
是要销毁的信号量。只有用sem_init
初始化的信号量才能用sem_destroy
销毁
信号令和锁的区别在于可以设置多个临界区的同时执行者,而被锁锁住的临界区只能由一个新鲜执行