Linux系统编程——线程

Linux系统编程–线程

1.线程概述(与进程的区别及线程的优势)

2.线程创建等待退出

3.线程共享内存空间的代码验证

4.线程同步之互斥量加锁解锁

5.互斥锁限制共享资源的访问

6.什么情况造成死锁

7.线程条件控制实现线程的同步

1.线程概述(与进程的区别及线程的优势)

Linux多线程编程初探 - 峰子_仰望阳光 - 博客园 (cnblogs.com)

线程也有竞争的关系。

2.线程创建等待退出

demo1.c

#include <pthread.h>
#include <stdio.h>

//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
        printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
        printf("parm is %d\n",*((int *)arg));

}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{

        int ret;
        pthread_t t1;
        int *pret = NULL;
        int parm = 100;
        ret  = pthread_create(&t1,NULL,funs,(void *)&parm); //创建线程
        if(ret == 0){
                printf("creat t1 is success\n");
		
        }
        return 0;
}

运行结果:在这里插入图片描述
编译时需要链上 -lpthread

运行结果与所想不一样(printf(“parm is %d\n”,*((int *)arg));)还没打印就已经结束了,是因为主程序中没有等待返回就已经结束了

demo2.c (返回 int类型)

#include <pthread.h>
#include <stdio.h>

//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
        static int ret =10;  //如果不用static 函数调用结束后就没掉了,会随机返回 
        printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
        printf("parm is %d\n",*((int *)arg));
        pthread_exit((void *)&ret);  //退出线程

}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{

        int ret;
        pthread_t t1;
        int *pret = NULL;
        int parm = 100;
        ret  = pthread_create(&t1,NULL,funs,(void *)&parm);
        if(ret == 0){
                printf("creat t1 is success\n");

        }
        printf("main:%ld\n",(unsigned long)pthread_self());
        pthread_join(t1,(void **)&pret); //等待线程退出·
    //pthread_join(t1,NULL);//如果对线程的返回值不感兴趣,可以把rval_ptr置为NULL。在这种情况下,调用pthread_join函数将等待指定的线程终止,但并								//不获得线程的终止状态。
        printf("main:t1 qiut:%d\n",*pret); 
        return 0;
}

运行结果:在这里插入图片描述

demo3.c (返回 char 类型)

#include <pthread.h>
#include <stdio.h>

//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
        static char *ret = "funs ret quit!";
        printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
        printf("parm is %d\n",*((int *)arg));
        pthread_exit((void *)ret);

}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{

        int ret;
        pthread_t t1;
        char *pret = NULL;
        int parm = 100;
        ret  = pthread_create(&t1,NULL,funs,(void *)&parm);
        if(ret == 0){
                printf("creat t1 is success\n");

        }
        printf("main:%ld\n",(unsigned long)pthread_self());
        pthread_join(t1,(void **)&pret);
        printf("main: t1 quit:%s\n",pret);
        return 0;
}

运行结果:在这里插入图片描述

3.线程共享内存空间的运行结果代码验证

demo4.c

#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
	printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	while(1){
		printf("t1_data:%d\n",data++);
		sleep(1);
        /*
		if(data == 4){				//t1不一定能获得4, 线程间相互竞争,有几率得到4
			pthread_exit(NULL); 	//if data == 4 ;退出t1线程
		}
		*/
	}
}
void *funs2(void *arg)
{
	printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	while(1){
		printf("t2_data:%d\n",data++);
		sleep(1);
	}
	
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{

	int ret;
	pthread_t t1;
	pthread_t t2;
	int *pret = NULL;
	int parm = 100;
	ret  = pthread_create(&t1,NULL,funs,(void *)&parm);
	if(ret == 0){
		printf("creat t1 is success\n");
		
	}
	ret  = pthread_create(&t2,NULL,funs2,(void *)&parm);
	if(ret == 0){
		printf("creat t2 is success\n");
	}
	while(1){
		printf("main_data:%d\n",data++);
		sleep(1);
	}
	pthread_join(t1,NULL);
	pthread_join(t2,NULL);
	return 0;
}

运行结果:在这里插入图片描述

4.线程同步之互斥量加锁解锁

demo5.c

#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex;//创建锁
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
	//int pthread_mutex_lock(*pthread_mutex_t mutex);
	pthread_mutex_lock(&mutex);//上锁
	printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	//int pthread_mutex_unlock(*pthread_mutext_mutex);
	pthread_mutex_unlock(&mutex);//解锁
}
void *funs2(void *arg)
{
	pthread_mutex_lock(&mutex);//上锁
	printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	pthread_mutex_unlock(&mutex);//解锁
	
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{

	int ret;
	pthread_t t1;
	pthread_t t2;
	int *pret = NULL;
	int parm = 100;
    pthread_mutex_init(&mutex, NULL); //锁动态初始化
	ret  = pthread_create(&t1,NULL,funs,(void *)&parm);
	if(ret == 0){
		printf("creat t1 is success\n");
	}
	ret  = pthread_create(&t2,NULL,funs2,(void *)&parm);
	if(ret == 0){
		printf("creat t2 is success\n");
	}
	pthread_join(t1,NULL);
	pthread_join(t2,NULL);
	//int pthread_mutex_destroy(*pthread_mutex_t mutex);
	pthread_mutex_destroy(&mutex);//销毁锁
	return 0;
}

运行结果:在这里插入图片描述

5.互斥锁限制共享资源的访问

demo6.c

#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex;
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
	//int pthread_mutex_lock(*pthread_mutex_t mutex);
	pthread_mutex_lock(&mutex);
	printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	//int pthread_mutex_unlock(*pthread_mutext_mutex);
	while(1){
		printf("t1:%d\n",data++);
		sleep(1);
		if(data == 4){

			pthread_mutex_unlock(&mutex);
			printf("t1 quit====================\n");
			pthread_exit(NULL);
		}
	}
}
/*让t1运行到4结束退出线程,刚开始不确定会是哪个线程先运行,到t2,上锁++后解锁,到t1上锁,等data=4时,解锁退出*/
void *funs2(void *arg)
{
	printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	while(1){
		printf("t2:%d\n",data);
		pthread_mutex_lock(&mutex);
		data++;
		pthread_mutex_unlock(&mutex);
		sleep(1);
	}
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{

	int ret;
	pthread_t t1;
	pthread_t t2;
	int *pret = NULL;
	int parm = 100;
    pthread_mutex_init(&mutex, NULL); //锁动态初始化
	ret  = pthread_create(&t1,NULL,funs,(void *)&parm);
	if(ret == 0){
		printf("creat t1 is success\n");
		
	}
	ret  = pthread_create(&t2,NULL,funs2,(void *)&parm);
	if(ret == 0){
		printf("creat t2 is success\n");
	}
	pthread_join(t1,NULL);
	pthread_join(t2,NULL);
	//int pthread_mutex_destroy(*pthread_mutex_t mutex);
	pthread_mutex_destroy(&mutex);
	return 0;
}

运行结果:在这里插入图片描述

6.什么情况造成死锁

demo7.c

#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex;
pthread_mutex_t mutex2;
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
	//int pthread_mutex_lock(*pthread_mutex_t mutex);
	pthread_mutex_lock(&mutex);
	sleep(1);
	pthread_mutex_lock(&mutex2);
	printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	//int pthread_mutex_unlock(*pthread_mutext_mutex);
	pthread_mutex_unlock(&mutex);
}
void *funs2(void *arg)
{
	pthread_mutex_lock(&mutex);
	sleep(1);
	pthread_mutex_lock(&mutex2);
	printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	pthread_mutex_unlock(&mutex);
	
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{

	int ret;
	pthread_t t1;
	pthread_t t2;
	int *pret = NULL;
	int parm = 100;
    pthread_mutex_init(&mutex, NULL); //锁动态初始化
    pthread_mutex_init(&mutex2, NULL); //锁动态初始化
	ret  = pthread_create(&t1,NULL,funs,(void *)&parm);
	if(ret == 0){
		printf("creat t1 is success\n");
		
	}
	ret  = pthread_create(&t2,NULL,funs2,(void *)&parm);
	if(ret == 0){
		printf("creat t2 is success\n");
	}
	pthread_join(t1,NULL);
	pthread_join(t2,NULL);
	//int pthread_mutex_destroy(*pthread_mutex_t mutex);
	pthread_mutex_destroy(&mutex);
	return 0;
}

要有两把锁,才能有死锁,当funs锁mutex时,funs2锁mutex2了,funs再想锁mutex2时就拿不到,会一直卡住,同理funs2也是。

使用多把锁时,一定要注意避免死锁

7.线程条件控制实现线程的同步

demo8.c

#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex;
pthread_cond_t cond;
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
	printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	while(1){
		//int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
		pthread_cond_wait(&cond,&mutex);	//等待触发条件
		printf("t1:%d\n",data);
		printf("t1 qiut================\n");
		data = 0;
		sleep(1);
	}
}
void *funs2(void *arg)
{
	printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	while(1){
		printf("t2:%d\n",data);
		pthread_mutex_lock(&mutex);
		data++;	
		pthread_mutex_unlock(&mutex);
		if(data == 4){
//int pthread_cond_signal(*pthread_cond_t cond);
			pthread_cond_signal(&cond); //触发条件
		}
		sleep(1);
	}
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{

	int ret;
	pthread_t t1;
	pthread_t t2;
	int *pret = NULL;
	int parm = 100;
     pthread_mutex_init(&mutex, NULL); //锁动态初始化
	//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
	pthread_cond_init(&cond,NULL); //条件动态初始化
	ret  = pthread_create(&t1,NULL,funs,(void *)&parm);
	if(ret == 0){
	//	printf("creat t1 is success\n");
		
	}
	ret  = pthread_create(&t2,NULL,funs2,(void *)&parm);
	if(ret == 0){
	//	printf("creat t2 is success\n");
	}
	pthread_join(t1,NULL);
	pthread_join(t2,NULL);

	//int pthread_mutex_destroy(*pthread_mutex_t mutex);
	pthread_mutex_destroy(&mutex);
//int pthread_cond_destroy(*pthread_cond_t cond);
	pthread_cond_destroy(&cond); //销毁条件
	return 0;
}

运行结果:在这里插入图片描述

此程序中会一直运行,因为data=0;一直都会在赋值。

#include <pthread.h>
#include <stdio.h>
int data = 0;
//int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex;
pthread_cond_t cond;
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
void *funs(void *arg)
{
    static int cnt = 3;
	printf("t1:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	while(1){
		//int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
		pthread_cond_wait(&cond,&mutex);	//等待触发条件
		printf("t1:%d\n",data);
		printf("t1 qiut================\n");
		data = 0;
		sleep(1);
        cnt--;
        if(cnt == 0){		//当cnt=0时;整个程序退出
            exit(-1);
        }
	}
}
void *funs2(void *arg)
{
	printf("t2:%ld\npthread is creat\n",(unsigned long)pthread_self());
	printf("parm is %d\n",*((int *)arg));
	while(1){
		printf("t2:%d\n",data);
		pthread_mutex_lock(&mutex);
		data++;	
		pthread_mutex_unlock(&mutex);
		if(data == 4){
//int pthread_cond_signal(*pthread_cond_t cond);
			pthread_cond_signal(&cond); //触发条件
		}
		sleep(1);
	}
}
//int pthread_exit(void *rval_ptr);
//int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
int main()
{

	int ret;
	pthread_t t1;
	pthread_t t2;
	int *pret = NULL;
	int parm = 100;
     pthread_mutex_init(&mutex, NULL); //锁动态初始化
	//int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
	pthread_cond_init(&cond,NULL); //条件动态初始化
	ret  = pthread_create(&t1,NULL,funs,(void *)&parm);
	if(ret == 0){
	//	printf("creat t1 is success\n");
		
	}
	ret  = pthread_create(&t2,NULL,funs2,(void *)&parm);
	if(ret == 0){
	//	printf("creat t2 is success\n");
	}
	pthread_join(t1,NULL);
	pthread_join(t2,NULL);

	//int pthread_mutex_destroy(*pthread_mutex_t mutex);
	pthread_mutex_destroy(&mutex);
//int pthread_cond_destroy(*pthread_cond_t cond);
	pthread_cond_destroy(&cond); //销毁条件
	return 0;
}

用程序测试:

int main(int argc,char **argv)
//int main()
{
        int i=0;
        int time;
        time = atoi(argv[1]);
//      time = 5;
        for(i = 0; i < time ;i++){
                system("./demo8");
        }
}

在这里插入图片描述

./a.out 10 >>test.txt &运行10次,将结果放在test.txt中,& 后台运行

运行结果:在这里插入图片描述
cond 和 mutex初始化

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//静态初始化
pthread_mutex_init(&mutex, NULL); //动态初始化
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;//静态初始化
pthread_cond_init(&cond, NULL); //动态初始化
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值