注意:在gcc文件的适合记得加上-lpthread
主线程记得调用pthread_join,防止主线程先于其他线程退出,导致代码没有执行
一、线程
线程所涉及的头文件:#include<pthread.h>
1、线程的创建:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr , void *(*start_routine) (void *), void *arg);
thread为线程ID;attr 默认情况下为NULL;start_routine为线程的操作函数名(即你想让线程干啥事);arg为start_routine函数所传递的参数
返回值:成功返回0,错误返回错误编号
2、线程的退出:
void pthread_exit(void *retval);
retval为退出码,可以为整型和字符串
3、线程的等待
int pthread_join(pthread_t thread, void **retval);
thread为主线程要等待的线程的ID;retval是线程退出后收集的退出码
返回值:若超过返回0,错误返回错误编号
demo1.c:
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func) (void *), void *arg);
struct pParam
{
int a;
char *b;
};
void pFunc(struct pParam *c)
{
static char *back = "the pthread qiut";
printf("ti:my pthread id = %ld\n",(unsigned long)pthread_self());
printf("param = %d\n",c->a);
printf("str = %s\n",c->b);
pthread_exit((void *)&back);
}
int main()
{
char *d = NULL;
pthread_t pth1;
struct pParam arg = {100,"caiqingfeng"};
if(pthread_create(&pth1,NULL,(void *)&pFunc,(void *)&arg) == -1){
printf("pthread_create fail!\n");
}
if(pthread_join(pth1,(void **)&d) != 0){
printf("pthread_join fail!\n");
}
printf("back = %s\n",d);
return 0;
}
~
~
~
二、互斥锁(能保证线程能完整运行)
1、互斥锁的创建:
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
mutex类似于互斥锁ID;attr常规情况下为NULL
返回值:若成功返回0,错误返回错误编号
2、互斥锁的销毁:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
mutex为互斥锁ID
返回值:若超过返回0,错误返回错误编号
3.加锁、解锁:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
mutex均为互斥锁的ID
返回值:若超过返回0,错误返回错误编号
#include <stdio.h>
#include <pthread.h>
//int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func) (void *), void *arg);
pthread_mutex_t mutex;
struct pParam
{
int a;
char *b;
};
void pFunc(struct pParam *c)
{
if(pthread_mutex_lock(&mutex) != 0){
printf("pth1: lock fail!\n");
}
static int back = 404;
printf("pth1: ti:my pthread id = %ld\n",(unsigned long)pthread_self());
printf("pth1: param = %d\n",c->a);
printf("pth1: str = %s\n",c->b);
if(pthread_mutex_unlock(&mutex) != 0){
printf("pth2: unlock fail!");
}
pthread_exit((void *)&back);
}
void pFunc2(struct pParam *c)
{
if(pthread_mutex_lock(&mutex) != 0){
printf("pth1: lock fail!\n");
}
static int back = 505;
printf("pth2: ti:my pthread id = %ld\n",(unsigned long)pthread_self());
printf("pth2: param = %d\n",c->a);
printf("pth2: str = %s\n",c->b);
if(pthread_mutex_unlock(&mutex) != 0){
printf("pth2: unlock fail!");
}
pthread_exit((void *)&back);
}
int main()
{
int *d = NULL;
int *d2 = NULL;
pthread_t pth1;
pthread_t pth2;
struct pParam arg = {100,"caiqingfeng"};
if(pthread_mutex_init(&mutex, NULL) != 0){
printf("mutex_init fail!\n");
}
if(pthread_create(&pth1,NULL,(void *)&pFunc,(void *)&arg) == -1){
printf("pthread_create fail!\n");
}
if(pthread_create(&pth2,NULL,(void *)&pFunc2,(void *)&arg) == -1){
printf("pthread_create fail!\n");
}
if(pthread_join(pth1,(void **)&d) != 0){
printf("pthread_join fail!\n");
}
if(pthread_join(pth2,(void **)&d2) != 0){
printf("pthread_join fail!\n");
}
if(pthread_mutex_destroy(&mutex) != 0){
printf("mutex_destroy fail!\n");
}
printf("pth1 :back = %d\n",*d);
printf("pth2 :back = %d\n",*d2);
return 0;
}
三、条件变量(可分配线程的运行顺序)
1.条件变量的创建:
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
cond为条件变量的ID;attr正常情况为NULL
返回值:若超过返回0,错误返回错误编号
2、条件变量的销毁:
int pthread_cond_destroy(pthread_cond_t cond);
cond为条件变量的ID
返回值:若超过返回0,错误返回错误编号
3、条件变量的触发及广播
int pthread_cond_signal(pthread_cond_t cond);
int pthread_cond_broadcast(pthread_cond_t cond);
cond为条件变量的ID
返回值:若超过返回0,错误返回错误编号
注:这两个函数可唤醒等待形态下的线程;区别在于pthread_cond_signal只能唤醒一个线程
而pthread_cond_broadcast可唤醒多个线程
4.条件变量的等待
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
cond为条件变量的ID;mutex为互斥锁的ID
返回值:若超过返回0,错误返回错误编号
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
#include <stdio.h>
#include <pthread.h>
int data = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;
struct pParam
{
int a;
char *b;
};
void pFunc(struct pParam *c)
{
static int back = 404;
printf("pth1: ti:my pthread id = %ld\n",(unsigned long)pthread_self());
while(1){
if(pthread_cond_wait(&cond,&mutex) != 0){
printf("cond wait fail!\n");
}
printf("pth1 run==================================\n");
data = 0;
pthread_exit((void *)&back);
}
void pFunc2(struct pParam *c)
{
static int back = 505;
printf("pth2: ti:my pthread id = %ld\n",(unsigned long)pthread_self());
while(1){
/*if(pthread_mutex_lock(&mutex) != 0){
printf("pth1: lock fail!\n");
}*/
sleep(1);
printf("data = %d\n",data++);
if(data == 3){
if(pthread_cond_signal(&cond) != 0){
printf("cond signal fail!\n");
}
}
/*if(pthread_mutex_unlock(&mutex) != 0){
printf("pth2: unlock fail!");
}*/
}
pthread_exit((void *)&back);
}
int main()
{
int *d = NULL;
int *d2 = NULL;
pthread_t pth1;
pthread_t pth2;
struct pParam arg = {100,"caiqingfeng"};
if(pthread_mutex_init(&mutex, NULL) != 0){
printf("mutex_init fail!\n");
}
if(pthread_cond_init(&cond,NULL) != 0){
printf("cond init fail!\n");
}
if(pthread_create(&pth1,NULL,(void *)&pFunc,(void *)&arg) == -1){
printf("pthread_create fail!\n");
}
if(pthread_create(&pth2,NULL,(void *)&pFunc2,(void *)&arg) == -1){
printf("pthread_create fail!\n");
}
if(pthread_join(pth1,(void **)&d) != 0){
printf("pthread_join fail!\n");
}
if(pthread_join(pth2,(void **)&d2) != 0){
printf("pthread_join fail!\n");
}
if(pthread_mutex_destroy(&mutex) != 0){
printf("mutex_destroy fail!\n");
}
if(pthread_cond_destroy(&cond) != 0){
printf("cond destroy fail!\n");
}
// printf("pth1 :back = %d\n",*d);
// printf("pth2 :back = %d\n",*d2);
return 0;
}