1.线程创建:
#include <pthread.h>
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,如果失败则返回错误代码。
2.线程终止
void pthread_exit(void * rval_ptr)
线程退出函数 其他线程可以通过 pthread_jion 得到这个 无类型指针 rval_ptr
int pthread_join (pthread_t tid, void **rval_ptr)
等待线程 tid 终止,调用线程将阻塞,直到 线程 tid 调用 pthrad_exit, 返回,或者被取消。 rval_ptr就是调用 exit 的参数,如果对返回值不感兴趣, 可以传递NULL
例程:
<span style="font-size:10px;"> #include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char message[] = "Hello World";
void *thread_function(void *arg)
{
printf("thread_function is running. Argument was %s\n", (char *)arg);
sleep(1);
strcpy(message, "Bye!");
pthread_exit("Thank you for your CPU time!"); //子线程退出
}
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!\n");
exit(EXIT_FAILURE);
}
printf("Waiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result); //主线程main等待子线程退出
if (res != 0)
{
perror("Thread join failed!\n");
exit(EXIT_FAILURE);
}
printf("Thread joined, it returned %s\n", (char *)thread_result);
//thread_result=""Thank you for your CPU time!"
printf("Message is now %s\n", message);
exit(EXIT_FAILURE);
}</span>
运行:
jia@jia-R467:~/桌面/pthread$ gcc pthread.c -o pthread -lpthread
jia@jia-R467:~/桌面/pthread$ ./pthread
Waiting for thread to finish...
thread_function is running. Argument was Hello World
Thread joined, it returned Thank you for your CPU time!
Message is now Bye!
pthread_exit(void *retval)本身返回的就是指向某个对象的指针,因此,pthread_join(pthread_t th, void **thread_return);中的thread_return是二级指针,指向线程返回值的指针。
可以看到,我们创建的新线程修改的数组message的值,而原先的线程也可以访问该数组。如果我们调用的是fork而不是pthread_create,就不会有这样的效果了。原因是fork创建子进程之后,子进程会拷贝父进程,两者分离,相互不干扰,而线程之间则是共享进程的相关资源。