【Linux】线程

LinuxC的线程与WindowsC的线程有一点的区别,由于线程涉及到操作系统,因此,所调用的库与部分语法有所不同,是很正常的。不过思想是一样的,什么是线程,我在很久之前的文章《【Java】线程并发、互斥与同步》(点击打开链接)已经写过。

下面主要用一个小例子,来说明Linux中线程的使用,如下图,就是一个简单的3,2,1倒数,每隔一秒i自减,输出i就这么简单。

【Linux】线程_第1张图片

具体程序如下:

#include <pthread.h>  
#include <stdio.h>  
#include <stdlib.h>
void *thread_function(void *arg){//这个函数的形式参数规定这样写,不能直接写成char *
	printf("%s",(char *)arg);
	int i=3;
	while(i>0){
		printf("%d\n",i);
		i--;
		sleep(1);//该线程挂起1秒
	}
	pthread_exit(NULL);//退出线程
}
int main(){
	pthread_t timer;//声明一个线程为timer
	if (pthread_create(&timer,NULL,thread_function,"开始3,2,1倒数\n")!=0){//指明线程timer的执行函数为thread_function,第4个参数为传参数给thread_function的形式参数arg的字符串
		printf("创建线程失败!程序结束!\n");
		exit(1);
	}
	pthread_join(timer,NULL);//等待timer这个线程结束才执行下面的代码
	return 0;
}

这里首先用到标准的输入输出库stdio.h用来打印,之后由于涉及的操作系统,还用到了exit(1)函数,因此stdlib.h也就一定要引的。而pthread.h则是本文的主角,其中pthread_t用户线程的声明,而pthread_create则用于线程与执行函数的绑定,这个函数是这样的:

1、int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

参数说明:thread:指向pthread_create类型的指针,用于引用新创建的线程。attr:用于设置线程的属性,一般不需要特殊的属性,所以可以简单地设置为NULL。*(*start_routine)(void *):传递新线程所要执行的函数地址。arg:新线程所要执行的函数的参数。调用如果成功,则返回值是0,如果失败则返回错误代码。

之后,需要用到pthread_join,让主函数int main()等待timer执行结束,才执行return 0,销毁一切,否则,timer还没有执行完毕,则整个程序被销毁了,看不到效果,这个函数是这样:

2、int pthread_join(pthread_t th, void **thread_return);

参数说明:th:将要等待的线程,线程通过pthread_create返回的标识符来指定。thread_return:一个指针,指向另一个指针,而后者指向线程的返回值,一般可以为空。

之后,在thread_function中,注意一切搞完结束线程。sleep则是关键字之一,用户挂起线程。

上述是整个程序,由于是在Linux中写程序,我们程序猿同时还要管理编译部分。

首先在thread_function中,用while而不用for,是不支持for(int x=;;)这样的声明形式,必须写成int x;for(x=;;)的形式,还不如用while,我真是晕死,你这是多老的编译器?多久没更新过呢?亲,老掉牙的VC6都支持这种用法!


另外,上述程序展示利用到pthread_create在main与thread_function传递消息,thread_function的函数名可以变,但形式参数是定死的,不可以因为省事,省去一个强制类型转化,而将其形式参数写成char *,否则过不了编译:

【Linux】线程_第2张图片

最后,将最最最重要的事情放在最后,由于pthread.h不在Linux的传统类库,因此编译的时候,必须同时链接-lpthread这个东西,否则过不了编译的。


你可能感兴趣的:(线程,linux,操作系统,计时器,linuxC)