目录
线程是操作系统能够并发执行的一个基本单元,它是进程的一个执行实例。线程与进程的区别在于,线程共享进程的地址空间,而进程之间地址空间是相互独立的。线程的创建和撤销比进程要简单,线程之间的切换也比进程之间的切换要快。
C/C++中提供了pthread库来支持线程的创建和管理。pthread库是Linux系统下的线程库,在Windows系统下不能直接使用。
pthread库需要声明头文件:
#include <pthread.h>
pthread库提供了以下函数来创建线程:
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine)(void *),
void *arg);
该函数用于创建一个新线程,参数thread指向新线程的标识符,attr指向线程属性,start_routine指向线程执行函数,arg指向线程执行函数的参数。
pthread_create函数如果创建线程成功,则返回值是0;否则,返回错误码。
pthread_create函数的错误码如下:
EAGAIN:系统中没有可用的线程。
EINVAL:参数attr无效。
EPERM:当前进程没有创建线程的权限。
ENOMEM:内存不足。
线程执行函数的声明如下:
void *thread_function(void *arg);
线程执行函数可以是任何C函数,但是该函数不能有返回值,并且该函数不能调用exit函数。
创建线程后,可以使用pthread_join函数等待一个线程结束,并获取该线程的退出状态。(线程阻塞函数,调用该函数则等到线程结束才继续运行)该函数的声明如下:
int pthread_join(pthread_t thread, void **retval);
参数thread指向要等待的线程,retval指向一个指针,该指针将存储线程的退出状态。
如果成功,则pthread_join函数的返回值是0;否则,返回错误码。
?pthread_join函数的错误码如下:
ESRCH:参数thread指向的线程不存在。
EDEADLK:当前线程尝试等待自己。
EINVAL:参数thread指向的线程已经结束。
EINTR:等待线程被中断。
下面是一个简单的线程创建和等待示例:
#include <stdio.h>
#include <pthread.h>
void *thread_function(void *arg) {
printf("This is a thread.\n");
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_function, NULL);
pthread_join(thread, NULL);
printf("Thread finished.\n");
return 0;
}
运行该程序,输出如下:
This is a thread.
Thread finished.
pthread_exit函数用于在线程中显式地退出线程,并返回一个指针值作为线程的退出状态。该函数的声明如下:
void pthread_exit(void *retval);
参数retval是一个指针,用于传递线程的退出状态。线程的退出状态可以是任何类型的指针。 pthread_exit函数没有返回值。 使用pthread_exit函数可以在任何地方显式地终止线程的执行,并将退出状态传递给等待该线程的其他线程。 下面是一个使用pthread_exit函数的示例:
#include <stdio.h>
#include <pthread.h>
void *thread_function(void *arg) {
printf("Thread is exiting.\n");
int *result = malloc(sizeof(int));
*result = 42;
pthread_exit(result);
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_function, NULL);
void *exit_status;
pthread_join(thread, &exit_status);
int *result = (int *)exit_status;
printf("Thread exited with status: %d\n", *result);
free(result);
return 0;
}
运行该程序,输出如下:
Thread is exiting.
Thread exited with status: 42
在上面的示例中,线程函数thread_function在退出之前动态分配了一个int类型的内存,并将其作为退出状态传递给pthread_exit函数。在主线程中,通过pthread_join函数获取线程的退出状态,并进行相应的处理。
pthread_self函数用于获取当前线程的线程标识符。该函数的声明如下:
pthread_t pthread_self(void);
pthread_self函数的返回值是当前线程的线程标识符。 pthread_self函数的使用示例如下:
#include <stdio.h>
#include <pthread.h>
void *thread_function(void *arg) {
printf("This is a thread.\n");
pthread_t thread_id = pthread_self();
printf("My thread id is %lu.\n", thread_id);
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_function, NULL);
pthread_join(thread, NULL);
return 0;
}
运行该程序,输出如下:
This is a thread.
My thread id is 140737440306016.
在上面这个例子中,创建了一个线程,并在线程中调用pthread_self函数来获取线程标识符。然后,在主线程中调用pthread_join函数来等待线程结束。当线程结束时,会在主线程中打印线程标识符。
pthread_cancel函数用于向指定的线程发送取消请求,请求线程退出。被取消的线程需要在适当的地方检查取消请求,并执行相应的清理操作。 pthread_cancel函数的声明如下:?
int pthread_cancel(pthread_t thread);
参数thread指向要取消的线程。
如果成功,则pthread_cancel函数的返回值是0;否则,返回错误码。 pthread_cancel函数的错误码如下:
ESRCH:参数thread指向的线程不存在
EINVAL:参数thread指向的线程已经结束
pthread_cancel函数的使用示例如下:
#include <stdio.h>
#include <pthread.h>
void *thread_function(void *arg) {
printf("This is a thread.\n");
while (1) {
// 检查是否被取消
if (pthread_cancel(pthread_self())) {
// 线程被取消,执行清理操作
break;
}
}
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_function, NULL);
// 等待线程结束
pthread_join(thread, NULL);
return 0;
}
运行该程序,输出如下:
This is a thread.
在上面这个例子中,创建了一个线程,并在主线程中调用pthread_cancel函数来取消该线程。当线程被取消时,它会执行清理操作,然后退出。
pthread_detach函数用于将指定的线程标记为可分离的,这样在线程终止时,系统会自动回收线程的资源,而不需要调用pthread_join来等待线程结束。 pthread_detach函数的声明如下:
int pthread_detach(pthread_t thread);
参数thread指向要分离的线程。
如果成功,则pthread_detach函数的返回值是0;否则,返回错误码。
pthread_detach函数的错误码如下:?
ESRCH:参数thread指向的线程不存在。
EINVAL:参数thread指向的线程已经结束。
pthread_detach函数的使用示例如下:
#include <stdio.h>
#include <pthread.h>
void *thread_function(void *arg) {
printf("This is a thread.\n");
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_function, NULL);
pthread_detach(thread);
return 0;
}
运行该程序,输出如下:
This is a thread.
在上面这个例子中,创建了一个线程,并调用pthread_detach函数将该线程标记为可分离的。当线程结束时,系统会自动回收线程的资源,而不需要调用pthread_join来等待线程结束。
pthread_equal函数用于比较两个线程标识符是否相等。该函数的声明如下:
int pthread_equal(pthread_t t1, pthread_t t2);
参数t1和t2是两个线程标识符。
如果两个线程标识符相等,pthread_equal函数的返回值是0;否则,返回非0值。
pthread_equal函数的使用示例如下:
#include <stdio.h>
#include <pthread.h>
void *thread_function(void *arg) {
return NULL;
}
int main() {
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, thread_function, NULL);
pthread_create(&thread2, NULL, thread_function, NULL);
if (pthread_equal(thread1, thread2)) {
printf("The two threads are equal.\n");
} else {
printf("The two threads are not equal.\n");
}
return 0;
}
运行该程序,输出如下:
The two threads are not equal.
在上面这个例子中,创建了两个线程,并使用pthread_equal函数比较它们是否相等。结果显示,两个线程是不相等的。