C/C++线程(pthread库)

发布时间:2024年01月17日

目录

1.概述

2.具体函数

2.1pthread_create创建线程

2.2pthread_join线程阻塞

2.3pthread_exit线程退出

2.4pthread_self获取线程标识

2.5pthread_cancel取消线程

2.6pthread_detach线程分离

2.7pthread_equal线程比较


1.概述

线程是操作系统能够并发执行的一个基本单元,它是进程的一个执行实例。线程与进程的区别在于,线程共享进程的地址空间,而进程之间地址空间是相互独立的。线程的创建和撤销比进程要简单,线程之间的切换也比进程之间的切换要快。

C/C++中提供了pthread库来支持线程的创建和管理。pthread库是Linux系统下的线程库,在Windows系统下不能直接使用。

pthread库需要声明头文件:

#include <pthread.h>

2.具体函数

2.1pthread_create创建线程

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函数

2.2pthread_join线程阻塞

创建线程后,可以使用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.

2.3pthread_exit线程退出

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函数获取线程的退出状态,并进行相应的处理。

2.4pthread_self获取线程标识

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函数来等待线程结束。当线程结束时,会在主线程中打印线程标识符。

2.5pthread_cancel取消线程

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函数来取消该线程。当线程被取消时,它会执行清理操作,然后退出。

2.6pthread_detach线程分离

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来等待线程结束。

2.7pthread_equal线程比较

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函数比较它们是否相等。结果显示,两个线程是不相等的。

文章来源:https://blog.csdn.net/m0_48465029/article/details/135625581
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。