博客文章

Linux的多线程

作者: andy.      时间: 2016-08-22 11:28:58

-lpthread。前面有一篇文章,在链接的时候有一个-l1,由此可以推断,在链接的时候加了pthread库。

好了,看看线程创建和其他的一些乱七八糟的操作。

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);第一个参数返回创建的线程ID,第二个参数为线程的初始化参数(一般为NULL,系统默认。就算创建被分离状态的线程也一样),第三个参数为回调函数(C#中的各种委托回调)。第四个参数为回调函数的参数。成功返回0,失败返回…鬼晓得失败返回啥子,反正不是0。

当我们想获得线程的返回值的时候,,int pthread_join(pthread_t thread, void **retval);就出现在了眼前,根据man的描述,第一个参数为线程ID,第二个参数就是去接收返回值的。返回值同上main。

int pthread_detach(pthread_t thread);设置线程分离状态,设置了的话,线程就处于放养状态。不能join,不能获得返回值什么的。

 好了,看代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

void * func(void *arg){
        int i = *(int *)arg;
        free(arg);
        int j = 0;
        for(j = 0; j < 5; j++){
                sleep(1);
                printf("%d\n", i);
        }

        int * result = malloc(sizeof(int));
        *result = 2013;
        pthread_exit(result);
}

pthread_t xoxo(){
        pthread_t thread;
        int * arg = malloc(sizeof(int));
        *arg = 1024;
        pthread_create(&thread, NULL, func, arg);

        return thread;
}

int main(){
        pthread_t thread = xoxo();

        int * result;
        pthread_join(thread, (void **)&result);
        printf("result:%d\n", *result);
        free(result);

        while(1){
                sleep(1);
        }
}

在xoxo函数中,传给回调函数的参数用了malloc,主要是防止回调函数在没有执行的时候,xoxo执行完成了内存回收了,那么回调函数再读取就出问题了。所以malloc后在回调函数中释放。看看运行结果:

[[email protected] thread]# ./a.out 
1024
1024
1024
1024
1024
result:2013
^C

pthread_detach函数就不做演示了。关于设置属性,属性的设置比较麻烦。看看man的描述:

blob.png

blob.png

可见,要先构造结构体,初始化该结构体。然后调用不同的函数初始化不同的项。


线程同步,这里介绍一个基础的。线程锁。类似于C#中的Lock。

使用方式先定义一个锁。用的时候加锁和解锁~

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_lock(pthread_mutex_t * mutex);
int pthread_mutex_unlock(pthread_mutex_t * mutex);

在线程的使用时,有一个函数int pthread_cancel(pthread_t thread);在一个线程中停止另外一个函数。试想一下,如果一个线程加锁后,在没有解锁的情况下被另外一个线程停止了。其他线程在加锁这儿就会死锁。

所以提供了一个函数int pthread_mutex_trylock(pthread_mutex_t *mutex);可以先解锁再停止线程。