Linux系统编程-线程

目录

一、线程

1、程序与线程

2、 Linux线程开发API

2.1、线程创建

2.2、线程退出

 2.3、线程等待

 2.4、线程ID获取

 例1:创建t1线程

2.5、创建与销毁互斥锁

2.6、加锁与解锁

例2:加锁

2.7、条件的创建与销毁

2.8、等待

2.9、触发


一、线程

1、程序与线程

  • 进程:是指⼀个内存中运⾏的应⽤程序,每个进程都有⼀个独⽴的内存空间,⼀个应⽤程序可以同时运⾏多个进程;进程也是程序的⼀次执⾏过程,是系统运⾏程序的基本单位;系统运⾏⼀个程序即是 ⼀个进程从创建、运⾏到消亡的过程。
  • 线程:线程是进程中的⼀个执⾏单元,负责当前进程中程序的执⾏,⼀个进程中⾄少有⼀个线程。⼀个进程中是可以有多个线程的,这个应⽤程序也可以称之为多线程程序。

2、 Linux线程开发API

对象操作API
 线程创建pthread_create
退出pthread_exit
等待pthread_join
互斥锁创建pthread_mutex_init
销毁pthread_mutex_destroy
加锁pthread_mutex_lock
解锁pthread_mutex_unlock
条件创建pthread_cond_init
销毁pthread_cond_destroy
触发pthread_cond_signal
广播pthread_cond_broadcast
等待pthread_cond_wait/pthead_cond_timedwat

2.1、线程创建

#include <pthread.h>

int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);

参数说明:

tidp:当线程成功创建后,tidp指向的内存单元被设置为新创建线程的线程ID。

attr:设置为NULL可以创建默认属性的线程。

start_rtn:新创建的线程从此函数开始运行,该函数只有一个无类型指针参数arg。如果需要向该函数传递的参数不止一个,则需要创建一个结构体放这些参数,然后把这个结构体的地址作为arg参数传入。

返回值:若成功返回0,否则返回错误编号

2.2、线程退出

#include <pthread.h>

int pthread_exit(void *rval_ptr);

参数说明:

rval_ptr:无类型的指针

 2.3、线程等待

调用这个函数的线程一直被阻塞

#include <pthread.h>

int pthread_join(pthread_t thread, void **rval_ptr);

 2.4、线程ID获取

#include <pthread.h>

pthread_t pthread_self(void);

返回值:线程ID

 例1:创建t1线程

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


//创建线程时,参数:函数(该线程需要做什么)
void *func1(void *arg)
{
	static char *p = "t1 is run out\n";
    //static:必须加上,否则线程结束,此数据也不存在
    //char型指针p是线程退出API的参数

	printf("t1:%ld thread is created\n",(unsigned long)pthread_self());
    //获取t1线程的ID,并转换成长整型

	printf("t1:param is %d\n",*((int *)arg));
    //将创建线程时函数参数打印出来(第4个参数)
    //*((int *)arg):arg为void型指针,强转为int型即:(int *)arg;
    //然后再取该地址中的数据,即*((int *)arg)


	pthread_exit((void *)p);
    //t1线程退出,会有一个指针参数(主线程join时要获取此参数)
    //将char型指针强转为void型指针
}

int main()
{
	int ret;//创建线程的返回值
	int param = 100;//第4个参数,函数的参数
	pthread_t t1;//线程名
	
	char *pret = NULL;//创建一个char型指针,为join接收t1线程的exit的参数

	ret = pthread_create(&t1,NULL,func1,(void *)&param);//创建线程
    //返回值为0,创建成功
	if(ret == 0){
		printf("main:create ti is success\n");
	}

	printf("main:%ld\n",(unsigned long)pthread_self());//打印主线程的ID

	pthread_join(t1,(void **)&pret);
    //等待t1退出,t1退出会给主线程传回一个参数,即第二个参数
    //第一个参数是线程名
    //第二个参数是一个void型的二级指针,pret本身就是一个char型指针,取它地址然后再强转void

	printf("main:t1 is quit:%s\n",pret);//将t1退出传回来的数据打印出来
	return 0;
}



运行结果:
main:create ti is success
main:140139917944576
t1:140139909658368 thread is created
t1:param is 100
main:t1 is quit:t1 is run out

2.5、创建与销毁互斥锁

锁的作用:上了锁的线程,一旦开始执行,不会被其他线程打断,直到该线程运行完成结束。

#include <pthread.h>

①创建

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

参数说明:

mutex:锁名

attr:NULL

②销毁

int pthread_mutex_destroy(pthread_mutex_t *mutex);

2.6、加锁与解锁

#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

例2:加锁

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

pthread_mutex_t m1;//锁名

void *func1(void *arg)
{
	int i;

	pthread_mutex_lock(&m1);//给线程1的执行函数加锁

	for(i=0;i<5;i++)
	{
		printf("t1:%ld thread is created\n",(unsigned long)pthread_self());
		printf("t1:param is %d\n",*((int *)arg));
		sleep(2);
	}

	pthread_mutex_unlock(&m1);//解锁
}


void *func2(void *arg)
{
	pthread_mutex_lock(&m1);//给线程2的执行函数加锁
	printf("t2:%ld thread is created\n",(unsigned long)pthread_self());
	printf("t2:param is %d\n",*((int *)arg));
	pthread_mutex_unlock(&m1);//解锁
}

int main()
{
	int ret;
	int param = 100;
	pthread_t t1;
	pthread_t t2;

	ret = pthread_create(&t1,NULL,func1,(void *)&param);
	if(ret == 0){
		printf("main:create t1 is success\n");
	}
	ret = pthread_create(&t2,NULL,func2,(void *)&param);
	if(ret == 0){
		printf("main:create t2 is success\n");
	}
	return 0;
}



运行结果:(t1先打印5次,每2秒一次,之后t2再执行,但是main没有锁会穿插其中)
main:create t1 is success
t1:139785596000000 thread is created
t1:param is 100
main:create t2 is success
t1:139785596000000 thread is created
t1:param is 100
t1:139785596000000 thread is created
t1:param is 100
t1:139785596000000 thread is created
t1:param is 100
t1:139785596000000 thread is created
t1:param is 100
t2:139785587607296 thread is created
t2:param is 100

2.7、条件的创建与销毁

条件的作用:当一个线程被锁住时,达到一定条件时,想让另一个线程去运行。

#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);

返回值:若成功返回0,失败返回错误编号

2.8、等待

条件被创建后,某一线程需要去等待这个条件成立,然后该线程去运行

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);

2.9、触发

 int pthread_cond_signal(pthread_cond_t cond);//单次触发

int pthread_cond_broadcast(pthread_cond_t cond); //广播

例3、线程t1当g_data=3时运行,线程t2上锁

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

pthread_mutex_t m;//锁名
pthread_cond_t c;//条件名

int g_data = 0;//临界资源

void *func1(void *arg)
{
	printf("t1:%ld thread is created\n",(unsigned long)pthread_self());
	printf("t1:param is %d\n",*((int *)arg));
	while(1){
		pthread_cond_wait(&c,&m);//t1线程等待条件成立
		printf("t1 run--------------\n");
		printf("t1:%d\n",g_data);
		g_data = 0;
		sleep(1);
	}
}


void *func2(void *arg)
{
	printf("t2:%ld thread is created\n",(unsigned long)pthread_self());
	printf("t2:param is %d\n",*((int *)arg));
	
	while(1){
		printf("t2:%d\n",g_data);
		pthread_mutex_lock(&m);//t2上锁
		g_data++;
		if(g_data == 3){
			pthread_cond_signal(&c);//触发条件
		}
		pthread_mutex_unlock(&m);//t2解锁
		sleep(1);
	}
}

int main()
{
	int ret;
	int param = 100;
	pthread_t t1;
	pthread_t t2;

	pthread_mutex_init(&m,NULL);//锁初始化
	pthread_cond_init(&c,NULL);//条件初始化
	
	ret = pthread_create(&t1,NULL,func1,(void *)&param);
	if(ret == 0){
	//	printf("main:create t1 is success\n");
	}
	ret = pthread_create(&t2,NULL,func2,(void *)&param);
	if(ret == 0){
	//	printf("main:create t2 is success\n");
	}

	pthread_mutex_destroy(&m);//销毁锁
	pthread_cond_destroy(&c);//销毁条件
	return 0;
}


运行结果:
t1:140324597438208 thread is created
t1:param is 100
t2:140324589045504 thread is created
t2:param is 100
t2:0
t2:1
t2:2
t1 run--------------
t1:3
t2:0
t2:1
t2:2
t1 run--------------
t1:3
t2:0
t2:1
t2:2
t1 run--------------
t1:3
t2:0
t2:1
t2:2
t1 run--------------
t1:3
t2:0
t2:1
t2:2
...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值