日期:2014-05-16  浏览次数:20661 次

(第四章 1)Linux多线程

相关函数定义在/usr/include/下,如/usr/include/pthread.h中。

参考文档:

Linux多线程编程 ?http://www.cnblogs.com/feisky/archive/2009/11/12/1601824.html

Linux下的多线程编程?http://fanqiang.chinaunix.net/a4/b8/20010811/0905001105.html

理解“内核线程”,"轻量级进程LWP","用户线程"?http://www.cnitblog.com/tarius.wu/articles/2277.html

POSIX(wiki):

?? ??an acronym for "Portable Operating System Interface", is a family of standards specified by the IEEE for maintaining compatibility between operating systems. POSIX defines the application programming interface (API), along with command line shells and utility interfaces, for software compatible with variants of Unix and other operating systems.

?

?

?

简单多线程编程

一、线程的绑定状态和游离状态

1. 创建的线程处于undetached状态

默认情况下,pthread_create()创建的线程为“被绑定状态(undetached)”,即,该线程被绑定到一个LWP上。

此时,线程线程终止时刻,并不马上释放自己占用的系统资源,而是由创建者调用pthread_join()等待其返回后释放它占用的系统资源。

?

2. 创建的线程处于detached状态

如果设置一个线程为“游离(detached)”线程,而这个线程运行又非常快,它很可能在pthread_create函数返回之前就终止了,它终止以后就可能将线程号和系统资源移交给其他的线程使用,这样调用pthread_create的线程就得到了错误的线程号。

要避免这种情况可以采取一定的同步措施,最简单的方法之一是可以在被创建的线程里调用pthread_cond_timewait函数,让这个线程等待一会儿,留出足够的时间让函数pthread_create返回。设置一段等待时间,是在多线程编程里常用的方法。但是注意不要使用诸如wait()之类的函数,它们是使整个进程睡眠,并不能解决线程同步的问题

?

二、编译指令

> gcc -g simple.c -lpthread -o simple

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

void thread(void){
	int i;
	for(i=0;i<10;i++){
		printf("This is a pthread.\n");
	}
}

int main(void){
	pthread_t id;
	int i;
	//int pthread_create(pthread_t *thread, pthread_attr_t *attr, void* (*start_routine)(void *), void *arg);
	if(!pthread_create(&id,NULL,(void*)thread,NULL)){
		printf("pthread_create() success!\n");

		//本函数等待被创建的线程返回才返回,并释放被创建线程占用的系统资源
		//void pthread_join(pthread_t th, void* thread_return); 其中*thread_return=retval
		pthread_join(id,NULL);

		for(i=0;i<3;i++){
			printf("this is the main process.\n");
		}
		//(1)主线程如果从main函数return或是调用exit函数退出,则整个进程终止(所有的其他线程也将终止);
		//(2)主线程调用pthread_exit函数,则仅主线程消亡,进程不会结束,其他线程不受影响。
		//pthread_exit(0);
		return 0;
	}else{
		printf("pthread_create() failure!\n");
		return 1;
	}
}
?

?

?

线程局部存储

两个线程对自己的私有数据操作是互相不影响的。也就是说,虽然 key 同名且全局,但访问的内存空间并不相同。key就像是一个数据管理员,线程的私有数据只是到他那去注册,让它知道你这个数据的存在。

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

pthread_key_t key;  //一个私有数据类型变量可以存放任意类型数据,使用时候强制转换即可

struct test_struct{
	int i;
	float k;
};

void print1(void){
	printf("0x%p\n",(struct test_struct*)pthread_getspecific(key));
	printf("%d, %f\n", ((struct test_struct*)pthread_getspecific(key))->i,
				((struct test_struct*)pthread_getspecific(key))->k);
}

void print2(void){
	printf("0x%p\n",(int*)pthread_getspecific(key));
	printf("%d\n", *((int*)pthread_getspecific(key)));
}

void *child1(void *arg){
	struct test_struct struct_data;
	struct_data.i=10;
	struct_data.k=3.1415;

	//每个线程就像访问全局变量那样访问变量key,实际上变量是线程私有的
	pthread_setspecific(key, &struct_data);

	printf("0x%p\n",&struct_data);
	print1();
}

void *child2(void *arg){
	int temp=20;
	sleep(2);
	
	pthread_setspecific(key,&temp);
	printf("0x%p\n",&temp);
	print2();
}

int main(void){
	pthread_t tid1,tid2;
	pthread_key_create(&key,NULL);			//

	pthread_create(&tid1,NULL,(void*)child1,NULL);
	pthread_create(&tid2,NULL,(void*)child2,NULL);
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);

	pthread_key_delete(key);			//