获取线程号
#include
pthread_t pthread_self(void);
成功:返回线程号
测试例程 1
#include
#include
int main()
{
pthread_t tid = pthread_self();
printf("tid = %lu\n",(unsigned long)tid);
return 0;
}
编译结果:
怎么创建线程呢?使用 pthread_create 函数:
创建线程
#include
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
#include
#include
#include
#include
void *fun(void *arg)
{
printf("pthread_New = %lu\n",(unsigned long)pthread_self());
}
int main()
{
pthread_t tid1;
int ret = pthread_create(&tid1,NULL,fun,NULL);
if(ret != 0){
perror("pthread_create");
return -1;
}
/*tid_main 为通过pthread_self获取的线程ID,tid_new通过执行pthread_create成功后tid指向的空间*/
printf("tid_main = %lu tid_new = %lu \n",(unsigned long)pthread_self(),(unsigned long)tid1);
/*因线程执行顺序随机,不加sleep可能导致猪线程先执行,导致进程结束,无法执行到子线程*/
sleep(1);
return 0;
}
#include
#include
#include
#include
void *fun1(void *arg)
{
printf("%s:arg = %d Addr = %p\n",__FUNCTION__,*(int *)arg,arg);
}
void *fun2(void *arg)
{
printf("%s:arg = %d Addr = %p\n",__FUNCTION__,(int)(long)arg,arg);
}
int main()
{
pthread_t tid1,tid2;
int a = 50;
int ret = pthread_create(&tid1,NULL,fun1,(void *)&a);
if(ret != 0){
perror("pthread_create");
return -1;
}
ret = pthread_create(&tid2,NULL,fun2,(void *)(long)a);
if(ret != 0){
perror("pthread_create");
return -1;
}
sleep(1);
printf("%s:a = %d Add = %p \n",__FUNCTION__,a,&a);
return 0;
}
测试例程 4:
#include
#include
#include
#include
void *fun1(void *arg)
{
while(1){
printf("%s:arg = %d Addr = %p\n",__FUNCTION__,*(int *)arg,arg);
sleep(1);
}
}
void *fun2(void *arg)
{
while(1){
printf("%s:arg = %d Addr = %p\n",__FUNCTION__,(int)(long)arg,arg);
sleep(1);
}
}
int main()
{
pthread_t tid1,tid2;
int a = 50;
int ret = pthread_create(&tid1,NULL,fun1,(void *)&a);
if(ret != 0){
perror("pthread_create");
return -1;
}
sleep(1);
ret = pthread_create(&tid2,NULL,fun2,(void *)(long)a);
if(ret != 0){
perror("pthread_create");
return -1;
}
while(1){
a++;
sleep(1);
printf("%s:a = %d Add = %p \n",__FUNCTION__,a,&a);
}
return 0;
}
运行结果:
#include
#include
#include
#include
#include
struct Stu{
int Id;
char Name[32];
float Mark;
};
void *fun1(void *arg)
{
struct Stu *tmp = (struct Stu *)arg;
printf("%s:Id = %d Name = %s Mark = %.2f\n",__FUNCTION__,tmp->Id,tmp->Name,tmp->Mark);
}
int main()
{
pthread_t tid1,tid2;
struct Stu stu;
stu.Id = 10000;
strcpy(stu.Name,"ZhangSan");
stu.Mark = 94.6;
int ret = pthread_create(&tid1,NULL,fun1,(void *)&stu);
if(ret != 0){
perror("pthread_create");
return -1;
}
printf("%s:Id = %d Name = %s Mark = %.2f\n",__FUNCTION__,stu.Id,stu.Name,stu.Mark);
sleep(1);
return 0;
}
线程主动退出
#include
void pthread_exit(void *retval);
线程被动退出,其他线程使用该函数让另一个线程退出
#include
int pthread_cancel(pthread_t thread);
成功:返回 0
线程资源回收(阻塞)
#include
int pthread_join(pthread_t thread, void **retval);
该函数为线程回收函数,默认状态为阻塞状态,直到成功回收线程后才返回。第一个参数为要回收线程的 tid 号,第二个参数为线程回收后接受线程传出的数据。
线程资源回收(非阻塞)
#define _GNU_SOURCE
#include
int pthread_tryjoin_np(pthread_t thread, void **retval);
测试例程 6:
#include
#include
#include
#include
void *fun1(void *arg)
{
static int tmp = 0;//必须要static修饰,否则pthread_join无法获取到正确值
//int tmp = 0;
tmp = *(int *)arg;
tmp+=100;
printf("%s:Addr = %p tmp = %d\n",__FUNCTION__,&tmp,tmp);
pthread_exit((void *)&tmp);
}
int main()
{
pthread_t tid1;
int a = 50;
void *Tmp = NULL;
int ret = pthread_create(&tid1,NULL,fun1,(void *)&a);//将变量以地址的形式传入线程,在线程中做出了自加100 的操作
if(ret != 0){
perror("pthread_create");
return -1;
}
pthread_join(tid1,&Tmp);
printf("%s:Addr = %p Val = %d\n",__FUNCTION__,Tmp,*(int *)Tmp);
return 0;
}
#include
#include
#include
#include
#include
struct Stu{
int Id;
char Name[32];
float Mark;
};
void *fun1(void *arg)
{
struct Stu *tmp = (struct Stu *)arg;
printf("%s:Id = %d Name = %s Mark = %.2f\n",__FUNCTION__,tmp->Id,tmp->Name,tmp->Mark);
}
int main()
{
pthread_t tid1,tid2;
struct Stu stu;
stu.Id = 10000;
strcpy(stu.Name,"ZhangSan");
stu.Mark = 94.6;
int ret = pthread_create(&tid1,NULL,fun1,(void *)&stu);
if(ret != 0){
perror("pthread_create");
return -1;
}
printf("%s:Id = %d Name = %s Mark = %.2f\n",__FUNCTION__,stu.Id,stu.Name,stu.Mark);
sleep(1);
return 0;
}
#define _GNU_SOURCE
#include
#include
#include
#include
void *fun1(void *arg)
{
printf("Pthread:1 come!\n");
while(1){
sleep(1);
}
}
void *fun2(void *arg)
{
printf("Pthread:2 come!\n");
pthread_cancel((pthread_t )(long)arg);
pthread_exit(NULL);
}
int main()
{
int ret,i,flag = 0;
void *Tmp = NULL;
pthread_t tid[2];
ret = pthread_create(&tid[0],NULL,fun1,NULL);
if(ret != 0){
perror("pthread_create");
return -1;
}
sleep(1);
ret = pthread_create(&tid[1],NULL,fun2,(void *)tid[0]);
if(ret != 0){
perror("pthread_create");
return -1;
}
while(1){
for(i = 0;i <2;i++){
if(pthread_tryjoin_np(tid[i],NULL) == 0){
printf("Pthread : %d exit !\n",i+1);
flag++;
}
}
if(flag >= 2) break;
}
return 0;
}
#define _GNU_SOURCE
#include
#include
#include
#include
int Num = 0;
void *fun1(void *arg)
{
while(Num < 3){
Num++;
printf("%s:Num = %d\n",__FUNCTION__,Num);
sleep(1);
}
pthread_exit(NULL);
}
void *fun2(void *arg)
{
while(Num > -3){
Num--;
printf("%s:Num = %d\n",__FUNCTION__,Num);
sleep(1);
}
pthread_exit(NULL);
}
int main()
{
int ret;
pthread_t tid1,tid2;
ret = pthread_create(&tid1,NULL,fun1,NULL);
if(ret != 0){
perror("pthread_create");
return -1;
}
ret = pthread_create(&tid2,NULL,fun2,NULL);
if(ret != 0){
perror("pthread_create");
return -1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}
int pthread_mutex_init(phtread_mutex_t *mutex, const pthread_mutexattr_t *restrict attr)
pthread_mutex_t mutex = PTHREAD_MUTEX_INITALIZER;
互斥量加锁(阻塞)/解锁
#include
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
成功:返回 0
互斥量加锁(非阻塞)
#include
int pthread_mutex_trylock(pthread_mutex_t *mutex);
互斥量销毁
#include
int pthread_mutex_destory(pthread_mutex_t *mutex);
成功:返回 0
#define _GNU_SOURCE
#include
#include
#include
#include
pthread_mutex_t mutex;//互斥量变量 一般申请全局变量
int Num = 0;//公共临界变量
void *fun1(void *arg)
{
pthread_mutex_lock(&mutex);//加锁 若有线程获得锁,则会阻塞
while(Num < 3){
Num++;
printf("%s:Num = %d\n",__FUNCTION__,Num);
sleep(1);
}
pthread_mutex_unlock(&mutex);//解锁
pthread_exit(NULL);//线程退出 pthread_join 会回收资源
}
void *fun2(void *arg)
{
pthread_mutex_lock(&mutex);加锁 若有线程获得锁,则会阻塞
while(Num > -3){
Num--;
printf("%s:Num = %d\n",__FUNCTION__,Num);
sleep(1);
}
pthread_mutex_unlock(&mutex);//解锁
pthread_exit(NULL);//线程退出 pthread_join 会回收资源
}
int main()
{
int ret;
pthread_t tid1,tid2;
ret = pthread_mutex_init(&mutex,NULL);//初始化互斥量
if(ret != 0){
perror("pthread_mutex_init");
return -1;
}
ret = pthread_create(&tid1,NULL,fun1,NULL);//创建线程 1
if(ret != 0){
perror("pthread_create");
return -1;
}
ret = pthread_create(&tid2,NULL,fun2,NULL);//创建线程 2
if(ret != 0){
perror("pthread_create");
return -1;
}
pthread_join(tid1,NULL);//阻塞回收线程 1
pthread_join(tid2,NULL);//阻塞回收线程 2
pthread_mutex_destroy(&mutex);//销毁互斥量
return 0;
}
#define _GNU_SOURCE
#include
#include
#include
#include
void *fun1(void *arg)
{
printf("%s:Pthread Come!\n",__FUNCTION__);
pthread_exit(NULL);
}
void *fun2(void *arg)
{
printf("%s:Pthread Come!\n",__FUNCTION__);
pthread_exit(NULL);
}
void *fun3(void *arg)
{
printf("%s:Pthread Come!\n",__FUNCTION__);
pthread_exit(NULL);
}
int main()
{
int ret;
pthread_t tid1,tid2,tid3;
ret = pthread_create(&tid1,NULL,fun1,NULL);
if(ret != 0){
perror("pthread_create");
return -1;
}
ret = pthread_create(&tid2,NULL,fun2,NULL);
if(ret != 0){
perror("pthread_create");
return -1;
}
ret = pthread_create(&tid3,NULL,fun3,NULL);
if(ret != 0){
perror("pthread_create");
return -1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_join(tid3,NULL);
return 0;
}
注意:信号量跟互斥量不一样,互斥量用来防止多个线程同时访问某个临界资源。信号量起通知作用,线程 A 在等待某件事,线程 B 完成了这件事后就可以给线程 A 发信号。
int sem_init(sem_t *sem,int pshared,unsigned int value);
#include
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
成功:返回 0
#include
int sem_trywait(sem_t *sem);
成功:返回 0
#include
int sem_destory(sem_t *sem);
成功:返回 0
#define _GNU_SOURCE
#include
#include
#include
#include
#include
sem_t sem1,sem2,sem3;//申请的三个信号量变量
void *fun1(void *arg)
{
sem_wait(&sem1);//因sem1本身有资源,所以不被阻塞 获取后sem1-1 下次会会阻塞
printf("%s:Pthread Come!\n",__FUNCTION__);
sem_post(&sem2);// 使得sem2获取到资源
pthread_exit(NULL);
}
void *fun2(void *arg)
{
sem_wait(&sem2);//因sem2在初始化时无资源会被阻塞,直至14行代码执行 不被阻塞 sem2-1 下次会阻塞
printf("%s:Pthread Come!\n",__FUNCTION__);
sem_post(&sem3);// 使得sem3获取到资源
pthread_exit(NULL);
}
void *fun3(void *arg)
{
sem_wait(&sem3);//因sem3在初始化时无资源会被阻塞,直至22行代码执行 不被阻塞 sem3-1 下次会阻塞
printf("%s:Pthread Come!\n",__FUNCTION__);
sem_post(&sem1);// 使得sem1获取到资源
pthread_exit(NULL);
}
int main()
{
int ret;
pthread_t tid1,tid2,tid3;
ret = sem_init(&sem1,0,1); //初始化信号量1 并且赋予其资源
if(ret < 0){
perror("sem_init");
return -1;
}
ret = sem_init(&sem2,0,0); //初始化信号量2 让其阻塞
if(ret < 0){
perror("sem_init");
return -1;
}
ret = sem_init(&sem3,0,0); //初始化信号3 让其阻塞
if(ret < 0){
perror("sem_init");
return -1;
}
ret = pthread_create(&tid1,NULL,fun1,NULL);//创建线程1
if(ret != 0){
perror("pthread_create");
return -1;
}
ret = pthread_create(&tid2,NULL,fun2,NULL);//创建线程2
if(ret != 0){
perror("pthread_create");
return -1;
}
ret = pthread_create(&tid3,NULL,fun3,NULL);//创建线程3
if(ret != 0){
perror("pthread_create");
return -1;
}
/*回收线程资源*/
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_join(tid3,NULL);
/*销毁信号量*/
sem_destroy(&sem1);
sem_destroy(&sem2);
sem_destroy(&sem3);
return 0;
}
函数原型如下:
#include
// 初始化条件变量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);//cond_at
tr 通常为 NULL
// 销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cond);
这些函数成功时都返回 0
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
pthread_mutex_lock(&g_tMutex);
// 如果条件不满足则,会 unlock g_tMutex
// 条件满足后被唤醒,会 lock g_tMutex
pthread_cond_wait(&g_tConVar, &g_tMutex);
/* 操作临界资源 */
pthread_mutex_unlock(&g_tMutex);
int pthread_cond_signal(pthread_cond_t *cond);
pthread_cond_signal(&g_tConVar);
#include
#include
#include
#include
#include
static char g_buf[1000];
static pthread_mutex_t g_tMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_tConVar = PTHREAD_COND_INITIALIZER;
static void *my_thread_func (void *data)
{
while (1)
{
//sleep(1);
/* 等待通知 */
//while (g_hasData == 0);
pthread_mutex_lock(&g_tMutex);
pthread_cond_wait(&g_tConVar, &g_tMutex);
/* 打印 */
printf("recv: %s\n", g_buf);
pthread_mutex_unlock(&g_tMutex);
}
return NULL;
}
int main(int argc, char **argv)
{
pthread_t tid;
int ret;
char buf[1000];
/* 1. 创建"接收线程" */
ret = pthread_create(&tid, NULL, my_thread_func, NULL);
if (ret)
{
printf("pthread_create err!\n");
return -1;
}
/* 2. 主线程读取标准输入, 发给"接收线程" */
while (1)
{
fgets(buf, 1000, stdin);
pthread_mutex_lock(&g_tMutex);
memcpy(g_buf, buf, 1000);
pthread_cond_signal(&g_tConVar); /* 通知接收线程 */
pthread_mutex_unlock(&g_tMutex);
}
return 0;
}