与传统的进程相比,用线程来实现相同的功能有如下优点:
编写linux下的线程需要包含头文件pthread.h
一个简单的多线程例子:
#include
#include
#include
static int run = 1;//运行状态参数
static int retvalue;//线程返回值
void *start_routine(void *arg) { //线程处理函数
int *running = arg;
printf("子线程初始化完毕, 传入参数为 %d\n",*running);
while(*running) {
printf("子线程正在运行\n");
usleep(1);
}
printf("子线程退出\n");
retvalue = 8;
pthread_exit((void*)&retvalue);
}
int main(int argc, char *argv[]) {
pthread_t pt;
int ret = -1;
int times = 3;
int i = 0;
int *ret_join = NULL;
ret = pthread_create(&pt, NULL, (void*)start_routine, &run);//建立线程
if(ret != 0 ) {
puts("建立线程失败");
return 1;
}
usleep(1);
for(;i<times;i++) {
puts("主线程打印");
usleep(1);
}
run = 0; //设置线程控制值,让线程退出
pthread_join(pt, (void*)&ret_join);
printf("线程返回值为 :%d\n",*ret_join);
return 0;
}
编译的时候记得要指定线程库gcc pthread.c -lpthread -o pthread
#include
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
//Compile and link with -pthread.
第一个参数是线程标识符,第二个参数用于设置线程的属性,为NULL时采用默认属性。第三个参数是一个返回值为void*,参数为void*的函数,是线程分配完资源后要执行的部分。线程函数运行时传入的参数,也就是第三个参数的函数需要传入的参数。
当线程创建成功时返回 0 ,否则表示失败了。常见的错误代码有EAGAIN、EINVAL,EAGAIN表示系统中的线程达到了上线,EINVAL表示线程的属性非法。线程创建成功后新创建的先按照参数3和4执行,原来的线程在线程创建函数返回后继续执行下一行代码。
函数pthread_join用来等待一个线程运行结束,这个函数是阻塞函数
#include
int pthread_join(pthread_t thread, void **retval);
//Compile and link with -pthread.
第一个参数是线程标识符,第二个参数是线程结束后返回的值。
线程函数(上述为start_routine)的结束方式有两种,一种是线程函数运行结束,不用返回结果,另一种是通过线程函数pthread_exit函数结束,函数的参数为 被捕获的返回值。
#include
void pthread_exit(void *retval);
//Compile and link with -pthread.
在上面用pthread_create创建函数的时候,使用了默认参数,即将第二个参数设为NULL,通常来说建立一个线程时使用默认属性就行了,但是很多时候需要调整线程的属性,特别是线程的优先级。
pthread_attr_t
线程属性的初始化函数是pthread_attr_init,这个函数必须在pthread_create之前调用。属性对象主要包括 线程的摘取状态、调度优先级、运行栈地址、运行栈大小、优先级。
#include
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);
//Compile and link with -pthread.
线程优先级是经常设置的属性,由两个函数进行控制,pthread_attr_getschedparam获得线程的优先级设置;函数pthread_attr_setschedparam设置线程的优先级。
#include
int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr,struct sched_param *param);
Compile and link with -pthread.
线程的优先级存放在结构sched_param中,其操作方式是先将优先级取出来,设置完后再放回去,