1 如何创建线程
创建线程步骤如下:
1.1 定义线程id
pthread_t pt
1.2 创建线程
参数解释:第一个参数为pthread_t*类型即线程id地址,第二个参数为线程属性一般使用默认属性NULL(0),第三个参数为线程执行的函数,函数定义的格式为void* threadFun(void*),第四个参数为线程函数传入的变量值的地址,如果不需要传入直接填写0即可
pthread_create(&pt,0,run,0);
1.3 等待线程退出
功能: 在主线程中等待线程退出,
参数介绍:第一个值为线程id,第二个值为线程结束后的返回值(void*)
pthread_join(pt,0);
1.4 详细代码
创建一个线程,主线程中等待,线程中打印10个数,详细代码如下
#include<stdio.h>
#include<pthread.h>
void* run(void* arg)
{
for(int i=0;i<10;i++){
printf("i=%i\n",i);
}
}
int main(int argc,char** argv)
{
pthread_t pt;
pthread_create(&pt,0,run,0);
pthread_join(pt,0);
return 0;
}
2 多线程问题
问题的引入,以下代码创建了两个线程,分别做10万次加法,最后的输出结果按道理来说是200000,但在实际情况中,这个值不一定就是200000,其中之一的运行结果,在代码部分下方,所以当访问相同的资源时候,可能会出现不同状况,那么如何解决这个问题呢,使用锁可以很好解决这个问题
#include<stdio.h>
#include<pthread.h>
int count = 0;
pthread_t pt1,pt2;
void* run1(void* arg)
{
for(int i=0;i<100000;i++)
{
count += 1;
}
}
void* run2(void* args)
{
for(int i=0;i<100000;i++)
{
count += 1;
}
}
int main(int argc,char**argv)
{
pthread_create(&pt1,0,run1,0);
pthread_create(&pt2,0,run2,0);
pthread_join(pt1,0);
pthread_join(pt2,0);
printf("count = %d\n",count);
return 0;
}
3 多线程锁
1.1 定义锁id
pthread_mutex_t mutex;
1.2 初始化锁和销毁锁
pthread_mutex_init传入参数两个,第一个锁id指针,第二个参数为“锁属性”,pthread_mutex_destory传入参数一个为锁id的指针
//初始化锁
pthread_mutex_init(&mutex,0);
//销毁锁
pthread_mutex_destroy(&mutex);
1.3 上锁和解锁
pthread_mutex_lock和pthread_mutex_unlock为保护代码执行,传入参数为锁id指针
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
1.4 详细代码
主要是在访问公共资源时候加锁,进行保护公共区资源,最终得到结果是200000,是正确的,利用锁可以有效保护对公共资源的操作准确性
#include<stdio.h>
#include<pthread.h>
int count = 0;
pthread_t pt1,pt2;
pthread_mutex_t mutex;
void* run1(void* arg)
{
for(int i=0;i<100000;i++)
{
pthread_mutex_lock(&mutex);
count += 1;
pthread_mutex_unlock(&mutex);
}
}
void* run2(void* args)
{
for(int i=0;i<100000;i++)
{
pthread_mutex_lock(&mutex);
count += 1;
pthread_mutex_unlock(&mutex);
}
}
int main(int argc,char**argv)
{
pthread_create(&pt1,0,run1,0);
pthread_create(&pt2,0,run2,0);
pthread_mutex_init(&mutex,0);
pthread_join(pt1,0);
pthread_join(pt2,0);
pthread_mutex_destroy(&mutex);
printf("count = %d\n",count);
return 0;
}
4、多线程条件量
4.1 定义条件量
pthread_cond_t cond;
4.2 初始化条件量和销毁条件量
pthread_cond_init(&cond,0);
pthread_cond_destroy(&cond);
4.3 条件量的等待和信号
pthread_cond_signal(&cond);
pthread_cond_wait(&cond);
4.4 详细代码
#include <stdio.h>
#include <pthread.h>
pthread_t t1,t2;
pthread_mutex_t m1,m2;
pthread_cond_t c;
void* r1(void*d)
{
while(1)
{
pthread_mutex_lock(&m1);
printf("我是等待!\n");
pthread_cond_wait(&c,&m1);
pthread_mutex_unlock(&m1);
}
}
void* r2(void *d)
{
while(1)
{
pthread_mutex_lock(&m1);
printf("我让你不再等待!\n");
pthread_cond_signal(&c);
//thread_cond_signal(&c);
pthread_mutex_unlock(&m1);
}
}
main()
{
pthread_cond_init(&c,0);
pthread_mutex_init(&m1,0);
pthread_mutex_init(&m2,0);
pthread_create(&t1,0,r1,0);
pthread_create(&t2,0,r2,0);
pthread_join(t1,0);
pthread_join(t2,0);
pthread_mutex_destroy(&m2);
pthread_mutex_destroy(&m1);
pthread_cond_destroy(&c);
}
5、多线程信号量
5.1 定义信号量
sem_t sem;
5.2 初始化信号量和销毁信号量
//初始化信号量
sem_init(&sem,0,0);
//销毁信号量
sem_destroy(&sem);
5.3 等待信号量和投递一个信号量
//投递信号量(增加)
sem_post(&sem);
//等待信号量(如果有信号量,不阻塞;
//如果没有信号量,等待信号量)
sem_wait(&sem);
5.4 详细代码
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
sem_t sem;
pthread_t pt1;
pthread_t pt2;
void* run1 (void* arg)
{
while(1)
{
printf("post sem before!\n");
sleep(2);
sem_post(&sem);
printf("post sem after!\n");
}
return NULL;
}
void* run2(void* arg)
{
while(1)
{
printf("wait sem before!\n");
sem_wait(&sem);
printf("wait sem after!\n");
}
return NULL;
}
int main(int argc,char** argv)
{
pthread_create(&pt1,0,run1,0);
pthread_create(&pt2,0,run2,0);
//初始化信号量
sem_init(&sem,0,0);
pthread_join(pt1,0);
pthread_join(pt2,0);
//销毁信号量
sem_destroy(&sem);
return 0;
}