Chinaunix首页 | 论坛 | 博客
  • 博客访问: 291000
  • 博文数量: 148
  • 博客积分: 4365
  • 博客等级: 上校
  • 技术积分: 1566
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-05 21:38
文章分类
文章存档

2014年(2)

2013年(45)

2012年(18)

2011年(1)

2009年(54)

2008年(28)

我的朋友

分类: LINUX

2009-03-16 17:06:19

线程又叫轻量级进程,通过多线程我们可以提高程序的效率,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()将其销毁。
阅读(878) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~