主要围绕以下图形来写
345原则
1.创建线程
原型:
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
当pthread_create成功返回时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数用于定制各种不同的线程属性,暂可以把它设置为NULL,以创建默认属性的线程。
新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg。如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg参数传入。
示例代码
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
void* fun1(void*arg)
{
printf(" thread is create\n T1 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
}
int main()
{
int ret;
pthread_t t1;
int param=100;
ret=pthread_create(&t1,NULL,fun1,(void*)¶m);
if(ret==0)
{
printf("main: Creat t1 is success\n");
}
printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id
pthread_join (t1,NULL);
return 0;
}
该代码中传递的参数为整型数,可修改为其他类型。
2.线程的退出和等待
#include <stdio.h>
#include <pthread.h>
#include <pthread.h> int pthread_join(pthread_t thread, void **rval_ptr);
如果对线程的返回值不感兴趣,可以把rval_ptr置为NULL。在这种情况下,调用pthread_join函数将等待指定的线程终止,但并不获得线程的终止状态。
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,void *(*start_rtn)(void*),void *arg);
//int pthread_join(pthread_t thread,void **value_ptr);
//void pthread_exit(void *retval);
void* fun1(void*arg)
{
static int ret =12;
printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
pthread_exit((void*)&ret);
}
int main()
{
int*pret=NULL;
int ret;
pthread_t t1;
int param=100;
ret=pthread_create(&t1,NULL,fun1,(void*)¶m);
if(ret==0)
{
printf("main: Creat t1 is success\n");
}
printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id
pthread_join (t1,(void**)&pret);
printf("Main: t1 quit:%d\n",*pret);
return 0;
}
返回值为 整型数
当返回值为字符串时,示例代码如下
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *tidp,const pthread_attr_t *attr,void *(*start_rtn)(void*),void *arg);
//int pthread_join(pthread_t thread,void **value_ptr);
//void pthread_exit(void *retval);
void* fun1(void*arg)
{
static char *p="t1 is run out!";
printf(" thread is create\n T1 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
pthread_exit((void*)p);
}
int main()
{
char*pret=NULL;
int ret;
pthread_t t1;
int param=100;
ret=pthread_create(&t1,NULL,fun1,(void*)¶m);
if(ret==0)
{
printf("main: Creat t1 is success\n");
}
printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id
pthread_join (t1,(void**)&pret);
printf("Main: t1 quit:%s\n",pret);
return 0;
}
3.线程之 共享内存验证
示例代码如下
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
int g_data=0;
void* fun1(void*arg)
{
printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
while(1)
{
printf("T1 :data is %d\n",g_data++);
sleep(1);
}
}
void* fun2(void*arg)
{
printf("thread is create\nT2 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
while(1)
{
printf("T2 :data is %d\n",g_data++);
sleep(1);
}
}
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
int param=100;
ret=pthread_create(&t1,NULL,fun1,(void*)¶m);
if(ret==0)
{
printf("main: Creat t1 is success\n");
}
ret=pthread_create(&t2,NULL,fun2,(void*)¶m);
if(ret==0)
{
printf("main: Creat t2 is success\n");
}
printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id
while(1)
{
printf("Main :data is %d\n",g_data++);
sleep(1);
}
pthread_join (t1,NULL);
pthread_join (t2,NULL);
return 0;
}
运行结果如下
main: Creat t1 is success
thread is create
T1 id is :140556216985344
param is 100
T1 :data is 0
thread is create
T2 id is :140556208592640
param is 100
T2 :data is 1
main: Creat t2 is success
Main id is :140556225271552
Main :data is 2
T1 :data is 3
Main :data is 5
T2 :data is 4
T1 :data is 6
Main :data is 7
T2 :data is 8
T1 :data is 9
T2 :data is 10
Main :data is 11
T1 :data is 12
T2 :data is 13
证明三个线程共同再争夺内存资源
4.互斥量加锁和解锁
原型:
创建和销毁
#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_unlock(pthread_mutex_t mutex);
示例代码如下:
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
//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_unlock(pthread_mutex_t *mutex);
int g_data=0;
pthread_mutex_t key;
void* fun1(void*arg)
{
int i=0;
pthread_mutex_lock(&key);
for(i=0;i<=5;i++)
{
printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
sleep(1);
}
pthread_mutex_unlock(&key);
}
void* fun2(void*arg)
{
printf("thread is create\nT2 id is :%ld\n",(unsigned long)pthread_self());//get id
}
void* fun3(void*arg)
{
printf("thread is create\nT3 id is :%ld\n",(unsigned long)pthread_self());//get id
}
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
pthread_t t3;
pthread_mutex_init(&key,NULL);
ret=pthread_create(&t1,NULL,fun1,NULL);
if(ret==0)
{
printf("main: Creat t1 is success\n");
}
ret=pthread_create(&t2,NULL,fun2,NULL);
if(ret==0)
{
printf("main: Creat t2 is success\n");
}
ret=pthread_create(&t3,NULL,fun3,NULL);
if(ret==0)
{
printf("main: Creat t3 is success\n");
}
printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id
pthread_join (t1,NULL);
pthread_join (t2,NULL);
pthread_join (t3,NULL);
pthread_mutex_destroy(&key);
return 0;
}
运行结果如下:
main: Creat t1 is success
thread is create
T1 id is :140546299254528
main: Creat t2 is success
thread is create
T2 id is :140546290861824
main: Creat t3 is success
Main id is :140546307540736
thread is create
T3 id is :140546282469120
thread is create
T1 id is :140546299254528
thread is create
T1 id is :140546299254528
thread is create
T1 id is :140546299254528
thread is create
T1 id is :140546299254528
thread is create
T1 id is :140546299254528
这段代码主要是给fun1加锁了,从运行结果中可以看到 fun1中的循环都是成对的
5.互斥锁限制共享资源的访问
为了实现 让g_data=3时让fun1线程退出这个功能,可以在循环开始前给他加锁,在g_data=3条件成立时给他解锁,然后执行exit(0)操作,让线程fun1退出。
示例代码如下:
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
//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_unlock(pthread_mutex_t *mutex);
pthread_mutex_t key;
int g_data=0;
void* fun1(void*arg)
{
printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
pthread_mutex_lock(&key);
while(1)
{
printf("T1 :data is %d\n",g_data++);
sleep(1);
if(g_data==3)
{
pthread_mutex_unlock(&key);
printf("T1 is quit =================!\n");
// pthread_exit(NULL);
exit(0);
}
}
}
void* fun2(void*arg)
{
printf("thread is create\nT2 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
while(1)
{
printf("T2 :data is %d\n",g_data);
pthread_mutex_lock(&key);
g_data++;
pthread_mutex_unlock(&key);
sleep(1);
}
}
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
int param=100;
pthread_mutex_init(&key,NULL);
ret=pthread_create(&t1,NULL,fun1,(void*)¶m);
if(ret==0)
{
printf("main: Creat t1 is success\n");
}
ret=pthread_create(&t2,NULL,fun2,(void*)¶m);
if(ret==0)
{
printf("main: Creat t2 is success\n");
}
printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id
while(1)
{
printf("Main :data is %d\n",g_data);
sleep(1);
}
pthread_join (t1,NULL);
pthread_join (t2,NULL);
pthread_mutex_destroy(&key);
return 0;
}
运行结果如下:
main: Creat t1 is success
thread is create
T1 id is :140554397001472
param is 100
T1 :data is 0
thread is create
T2 id is :140554388608768
param is 100
T2 :data is 1
main: Creat t2 is success
Main id is :140554405287680
Main :data is 1
T1 :data is 1
Main :data is 2
T1 :data is 2
Main :data is 3
T1 is quit =================!
从运行结果可以发现,当data等于3时,T1退出了
6. 条件控制
原型:
条件的创建与销毁:
#include <pthread.h> int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); int pthread_cond_destroy(pthread_cond_t cond);
等待和触发:
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
int pthread_cond_signal(pthread_cond_t cond);
对于刚才让g_data=3时让fun1线程退出还有另一种办法,就是使用条件来实现
具体方法:在fun1中一直等待,在fun2中判断 如果g_data=3时,让条件进行触发,然后fun1中等待收到了信号,往下执行。
示例代码如下:
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
//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_unlock(pthread_mutex_t *mutex);
//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
//int pthread_cond_destroy(pthread_cond_t cond);
//int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
//int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);
//int pthread_cond_signal(pthread_cond_t cond);
//int pthread_cond_broadcast(pthread_cond_t cond);
pthread_mutex_t key;
pthread_cond_t cond;
int g_data=0;
void* fun1(void*arg)
{
printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
pthread_mutex_lock(&key);
while(1)
{
pthread_cond_wait(&cond,&key);
printf("T1 run ==========================\n");
printf("T1 :data is %d\n",g_data);
g_data=0;
sleep(1);
}
}
void* fun2(void*arg)
{
printf("thread is create\nT2 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
while(1)
{
printf("T2 :data is %d\n",g_data);
pthread_mutex_lock(&key);
g_data++;
if(g_data==3)
{
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&key);
sleep(1);
}
}
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
int param=100;
pthread_mutex_init(&key,NULL);
pthread_cond_init(&cond,NULL);
ret=pthread_create(&t1,NULL,fun1,(void*)¶m);
if(ret==0)
{
//rintf("main: Creat t1 is success\n");
}
ret=pthread_create(&t2,NULL,fun2,(void*)¶m);
if(ret==0)
{
//rintf("main: Creat t2 is success\n");
}
// printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id
pthread_join (t1,NULL);
pthread_join (t2,NULL);
pthread_mutex_destroy(&key);
pthread_cond_destroy(&cond);
return 0;
}
7.初始化的两种方法
在进行初始化操作时,有两种方法:
分别为动态初始化和静态初始化
动态初始化:
pthread_mutex_t mutex; //dynamic init
pthread_cond_t cond; //dynamic init主函数中必须:
pthread_mutex_init(&mutex, NULL); //dynamic init
pthread_cond_init(&cond, NULL); //dynamic init使用宏进行初始化(静态初始化):
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // static init
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // static init
下面是示例代码:
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
//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_unlock(pthread_mutex_t *mutex);
//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
//int pthread_cond_destroy(pthread_cond_t cond);
//int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
//int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);
//int pthread_cond_signal(pthread_cond_t cond);
//int pthread_cond_broadcast(pthread_cond_t cond);
pthread_mutex_t key=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
int g_data=0;
void* fun1(void*arg)
{
printf("thread is create\nT1 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
pthread_mutex_lock(&key);
while(1)
{
pthread_cond_wait(&cond,&key);
printf("T1 run ==========================\n");
printf("T1 :data is %d\n",g_data);
g_data=0;
sleep(1);
}
}
void* fun2(void*arg)
{
printf("thread is create\nT2 id is :%ld\n",(unsigned long)pthread_self());//get id
printf("param is %d\n",*(int*)arg);
while(1)
{
printf("T2 :data is %d\n",g_data);
pthread_mutex_lock(&key);
g_data++;
if(g_data==3)
{
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&key);
sleep(1);
}
}
int main()
{
int ret;
pthread_t t1;
pthread_t t2;
int param=100;
// pthread_mutex_init(&key,NULL);
// pthread_cond_init(&cond,NULL);
ret=pthread_create(&t1,NULL,fun1,(void*)¶m);
if(ret==0)
{
//rintf("main: Creat t1 is success\n");
}
ret=pthread_create(&t2,NULL,fun2,(void*)¶m);
if(ret==0)
{
//rintf("main: Creat t2 is success\n");
}
// printf("Main id is :%ld\n",(unsigned long)pthread_self());//get id
pthread_join (t1,NULL);
pthread_join (t2,NULL);
pthread_mutex_destroy(&key);
pthread_cond_destroy(&cond);
return 0;
}
在使用静态初始化时,只需要通过宏定义来初始化就行,不需要再一次在main函数中进行初始化。
以上是线程的所有内容。