05-Linux并发程序设计-线程专题学习记录(华清创客)

线程概念(了解)

进程

  • 进程有独立 的地址空间
  • linux为每隔进程穿件task_struct
  • 每个进程都参与内核调度,互不影响
    线程
  • 进程在切换时系统开销大
  • 很多操作系统引入了轻量级进程LWP
  • 同一进程中的线程共享相同地址空间
  • linux不区分进程、线程

线程特点(了解)

  • 通常线程指的是共享相同地址空间的多个任务

  • 使用多个线程的好处
    大大提高了任务切换的效率
    避免额外的TLB&cache的刷新

  • 线程共享资源
    可执行的命令
    静态数据
    进程中打开的文件描述符
    当前工作目录
    用户ID
    用户组 ID

  • 线程私有资源
    线程ID(TID)
    PC和相关寄存器
    堆栈
    错误号
    优先级
    执行状态和属性

线程创建(熟练)

创建pthread_create

#include <pthread.h>
int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void*(*routine)(void*),void *arg);
//成功返回0,失败返回错误码
//thread线程对象
//attr线程属性,NULL代表默认属性
//routine线程执行的函数,线程创建的时候,会执行该函数
//arg传递给routine的参数

删除pthread_join

#include <pthread.h>
int pthread_join(pthread_t thread,void **retval);
//成功返回0,失败返回错误码
//thread要回收的线程对象
//调用线程阻塞直到thread结束
//*retval接收线程thread的返回值

结束pthread_exit

#include <pthread.h>
void pthread_exit(void *retval);
//结束当前线程
//retval可被其它线程通过pthread_join获取(不能是局部变量)
//线程私有资源被释放

线程 e.g.

char message[32] = "Hello Worle";
void *thread_func(void *arg);

void *thread_func(void *arg){
	sleep(1);
	strcpy(message,"marked by thread");
	pthread_exit("thank you for waiting for me");
}

int main(void){
	pthread_t a_thread;
	void *result;
	if(pthread_create(&a_thread,NULL,&thread_func,NULL) != 0){
		printf("fail to pthread_create");
		exit(-1);
	}
	pthread_join(a_thread,&result);
	printf("result is %s\n",result);
	printf("message is %s\n",message);
	return 0;
}

$gcc -o test test.c -lpthread //添加链接选项-l
$./test
thank you for waiting for me
marked by thread

线程通信

同步-POSIX信号量

  • POSIX定义的两类信号量

    无名信号量(基于内存的信号量):一般用于线程间通信
    有名信号量,可用于进程或线程间通信

  • pthread库常用的信号量操作函数:
    int sem_init(sem_t *sem,int pshared,unsigned int value);
    int sem_wait(sem_t *sem);//P操作
    int sem_post(sem_t *sem);//V操作

#include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned int val);
//success return 0 ,faile return EOF
//sem point to semaphore handle
//pshared 0 for thread ,1 for process
//val 信号量初值

e.g.

//生产者和消费者
char buf[32];
sem_t sem;
void *funtion(void *arg);
int main(void){
	pthread_t a_thread;
	if(sem_init(&sem,0,0) < 0){//信号量初始值为0,没有资源
		perror("sem_init");
		exit(-1);
	}
	if(pthread_create(&a_thread,NULL,function,NULL) != 0){
		printf("fail to pthread_create");
		exit(-1);
	}
	printf("input 'quit' to exit\n");
	do{
		fgets(buf,32,stdin);
		sem_post(&sem);
	}while(srtncmp(buf,"quit",4) != 0);
	return 0;
}
void *function(void *arg){
	while(1){
		sem_wait(&sem);
		printf("you enter %d characters\n",strlen(buf));
	}
}

ps aux -L |grep sem //查看线程状态

互斥

  • 临界资源
    包括数组、全局变量等全局缓存,不能多线程同时访问
    一次只允许一个任务(进程、线程)访问的共享资源
  • 临界区
    访问临界区的代码
  • 互斥机制
    mutex互斥锁
    任务访问临界资源前申请锁,访问完之后释放锁

互斥锁初始化-pthread_mutex_init

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
//成功返回0,失败返回错误码
//mutex指向要初始化的互斥锁对象
//如果无法获得锁,任务阻塞

释放锁-pthread_mutex_unlock

#jinclude <pthread.h>
int pthread_mutex_unlock(pthread_mutex_t *mutex);
//success 0  failed error code
//mutex
//执行完临界区要及时释放锁

L5-D3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值