线程又叫轻量级进程,通过多线程我们可以提高程序的效率,POSIX线程其实也是通过系统调用clone实现的。
使用POSIX线程需要引入
创建一个线程使用的函数是
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void *restrict arg);
看着复杂,用着简单,第一个参数为线程标示符指针,第二个为线程属性指针,第三个为线程的执行函数指针,最后一个为传递的参数。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
void *thread_function(void *arg);
char message[] = "Hello World";
int main() {
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, (void *)message);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
printf("Waiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined, it returned %s\n", (char *)thread_result);
printf("Message is now %s\n", message);
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg) {
printf("thread_function is running. Argument was %s\n", (char *)arg);
sleep(3);
strcpy(message, "Bye!");
pthread_exit("Thank you for the CPU time");
}
|
POSIX线程程序链接时要带 -lpthread 参数,用到pthread库
运行结果为
thread_function is running. Argument was Hello World
Waiting for thread to finish...
Thread joined, it returned Thank you for the CPU time
Message is now Bye!
注意的地方是POSIX线程函数大部分失败时并不返回-1,返回的是错误代码,所以返回值检查时一定要慎重
int pthread_join(pthread_t thread, void **value_ptr);
pthread_join函数用来归并线程,第一个参数是要归并的线程号,第二个参数存储线程推出的相关信息。
线程退出后,系统分配给它的资源并没有回收,有两种方法,一种是用该函数将线程归并,另一种是将线程设置为脱离状态的。
将线程设置成脱离状态也有两种方法,简单的是调用pthread_detach 函数
int pthread_detach(pthread_t thread);
参数是目标线程号,如果要把自己设置为脱离的,可以用pthread_self()函数得到自己的线程号
pthread_detach(pthread_self());
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
void *thread_function(void *arg);
char message[] = "Hello World";
int main() {
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
printf("Waiting for thread to finish...\n");
printf("Message is now %s\n", message);
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg) {
printf("thread is %d\n",pthread_self());
printf("thread_function is running. Argument was %s\n", message);
pthread_detach(pthread_self());
sleep(3);
strcpy(message, "Bye!");
printf("after sleep\n");
pthread_exit("Thank you for the CPU time");
}
|
程序有个改动需要注意,在创建线程时,传递的参数设置为NULL,但线程仍可访问message字符数组,这是因为message定义在全局域,是所有线程共享的。运行结果为:
thread is -1207899248
thread_function is running. Argument was Hello World
Waiting for thread to finish...
Message is now Hello World
很明显创建的线程还没有执行完毕,主线程退出时,新线程也随之结束了,这是因为主线程(main函数)中最后调用的是exit()函数,如果想主线程结束后,新线程仍在运行,可把exit()换位pthread_exit()
改变后程序运行结果为:
thread is -1208489072
thread_function is running. Argument was Hello World
Waiting for thread to finish...
Message is now Hello World
after sleep
看到了新线程的 输出 after sleep
使用线程属性则有一些繁琐,线程有很多属性,常用的就是脱离属性
int res;
pthread_t a_thread;
void *thread_result;
pthread_attr_t thread_attr;
res = pthread_attr_init(&thread_attr);
if (res != 0) {
perror("Attribute creation failed");
exit(EXIT_FAILURE);
}
res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
if (res != 0) {
perror("Setting detached attribute failed");
exit(EXIT_FAILURE);
}
res = pthread_create(&a_thread, &thread_attr, thread_function, (void *)message);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
(void)pthread_attr_destroy(&thread_attr);
|
上面的代码先创建一个线程属性,设置其脱离状态,然后传递给pthread_create函数,这样创建出来的线程直接就是脱离的,在使用完这个属性创建线程后,要用pthread_attr_destroy()将其销毁。
阅读(907) | 评论(0) | 转发(0) |