Linux 多线程 demo

一、线程简介

线程是一个进程内的基本调度单位,好比轻量级的进程。
多个线程在一个进程的共享内存空间中并发执行,它们共享一个进程的资源,如文件描述符和信号处理等,大大减少了上下文的开销。 运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而 且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。
总的说来, 一个进程的开销大约是一个线程开销的 30 倍左右。 不同进程具有独立的数据空间,其数据的传递只能通过通信的方式进行,费时且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,不仅快捷,而且方便。
使用多线程能带来更方便的通信机制。 多线程程序作为一种多任务、并发的工作方式,有以下几大优点:
(1) 提高应用程序响应;
(2)使多 CPU 系统更加有效;
(3)改善程序结构。

二、线程API

Linux 中的 pthread 库提供了大量的 API 函数,为用户编写多线程应用程序提供丰富支持。

1.线程创建

int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
// 返回:若成功返回0,否则返回错误编号

第一个参数为指向线程标识符的指针;
第二个参数用来设置线程属性,设为空指针时将生成默认属性的线程;
第三个参数是线程运行函数的起始地址;
最后一个参数是运行函数的参数,不需要参数时最后一个参数设为空指针 NULL。
当创建线程成功时,函数返回 0,若不为 0 则说明创建线程失败。 创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。

2.线程等待

#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);

函数 pthread_join 用来等待一个线程的结束,相当于进程中的 wait()系统调用。
pthread_join()将当前线程挂起,等待线程结束。这个函数是一个线程阻塞函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待 线程的资源才被收回。
第一个参数为被等待的线程标识符;
第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。

3.线程退出

#include <pthread.h>
int pthread_exit(void *rval_ptr);

一个线程的结束有两种途径,一种是函数结束了,调用它的线程也就结束 了;另一种方式是通过函数 pthread_exit 来实现。
唯一的参数是函数的返回代码,也就是 pthread_exit()调用者线程的返回值, 可由 pthread_join 来检索获取。只要 pthread_join 中的第二个参数rval_ptr不是 NULL,这个值将被传递给 rval_ptr。

4. 线程脱离

pthread_detach函数把指定的线程转变为脱离状态。

#include <pthread.h>
int pthread_detach(pthread_t thread);

若成功返回0,否则返回错误编号,本函数通常由想让自己脱离的线程使用,就如以下语句:

pthread_detach(pthread_self());

5.线程ID获取及比较

#include <pthread.h>
pthread_t pthread_self(void);

返回:调用线程的ID

三、互斥锁机制API

1.创建及销毁互斥锁

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

返回:若成功返回0,否则返回错误编号
要用默认的属性初始化互斥量,只需把attr设置为NULL。

2. 加锁及解锁

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

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

四、条件变量API

1.创建及销毁条件变量

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

除非需要创建一个非默认属性的条件变量,否则pthread_cont_init函数的attr参数可以设置为NULL。

2. 等待

#include <pthread.h>
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);

3. 触发

#include <pthread.h>
int pthread_cond_signal(pthread_cond_t cond);
int pthread_cond_broadcast(pthread_cond_t cond);

五、示例

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

static a = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;

void *fun1(void *arg)
{
//	static char *p = "this is t1 out\n";
	printf("t1: %ld is create\n",(unsigned long)pthread_self());
	printf("t1:value is %d\n",*((int *)arg));
	int cnt = 1;
	while(1){
			pthread_cond_wait(&cond, &mutex);
			printf("t1 run=====================\n");
			printf("t1 :%d\n",a++);
			a = 0;
			if(cnt++ == 5){
				exit(0);
			}
			sleep(1);
	}
//	pthread_exit((void *)p);
}

void *fun2(void *arg)
{
	printf("t2: %ld is create\n",(unsigned long)pthread_self());
	printf("t2:value is %d\n",*((int *)arg));
	while(1){
		pthread_mutex_lock(&mutex);
		printf("t2 :%d\n",a++);
		if(a == 3)
			pthread_cond_signal(&cond);
		pthread_mutex_unlock(&mutex);
		sleep(1);
	}
}
int main()
{
	pthread_t t1,t2;	
	int ret1,ret2;
	int pro = 100;
	char *p;
	pthread_mutex_init(&mutex,NULL);
	pthread_cond_init(&cond, NULL);
	
	ret1 = pthread_create(&t1,NULL,fun1,(void *)&pro);
	ret2 = pthread_create(&t2,NULL,fun2,(void *)&pro);
	
	pthread_join(t1,NULL);
	pthread_join(t2,NULL);
//	printf("main: ti quit : %s\n",p);
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值