pthread

线程:线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
线程程序作为一种多任务、并发的工作方式,当然有其存在优势:使多CPU系统更加有效:操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上

线程创建
函数原型:int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict attr,void *(*start_rtn)(void),void *restrict arg);
返回值:若是成功建立线程返回0,否则返回错误的编号。
形式参数:pthread_t*restrict tidp要创建的线程的线程id指针;const pthread_attr_t *restrict attr创建线程时的线程属性;void *(start_rtn)(void)返回值是void类型的指针函数;void *restrict arg start_rtn的形参。

线程挂起:

该函数的作用使得当前线程挂起,等待另一个线程返回才继续执行。也就是说当程序运行到这个地方时,程序会先停止,然后等线程id为thread的这个线程返回,然后程序才会断续执行。
函数原型:int pthread_join(pthread_tthread, void **value_ptr);
参数说明如下:thread等待退出线程的线程号;value_ptr退出线程的返回值。
返回值:若成功,则返回0;若失败,则返回错误号。

线程退出
函数原型:void pthread_exit(void *rval_ptr);
获取当前线程id
函数原型:pthread_tp thread_self(void);

互斥锁
创建pthread_mutex_init;销毁pthread_mutex_destroy;加锁pthread_mutex_lock;解锁pthread_mutex_unlock。

条件锁
创建pthread_cond_init;销毁pthread_cond_destroy;触发pthread_cond_signal;广播pthread_cond_broadcast;等待pthread_cond_wait。

 

undefined reference to 'pthread_create'
undefined reference to 'pthread_join'
问题原因:
    pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a,所以在使用pthread_create()创建线程,以及调用 pthread_atfork()函数建立fork处理程序时,需要链接该库。
问题解决:
    在编译中要加 -lpthread参数
    gcc a.c -o a.out -lpthread
    加上头文件#include<pthread.h>

Java中主线程退出了,子线程可能还在运行,直到运行完毕才自己结束。

C语言中主线程退出了,它会杀死子线程(如果用phread_create()创建线程,而没有使用pthread_join 或 pthread_detach)。

 

每个进程pthread_create创建以后都应该调用pthread_join 或 pthread_detach 函数,只有这样在线程结束的时候资源(线程的描述信息和stack)才能被释放.

When a joinable thread terminates, its memory resources (thread descriptor and stack) are not deallocated until another thread performs pthread_join on it.
Therefore, pthread_join must be called  once  for each joinable thread created to avoid memory leaks.
如果在新线程里面没有调用pthread_join 或 pthread_detach会导致内存泄漏, 如果你创建的线程越多,你的内存利用率就会越高, 直到你再无法创建线程,最终只能结束进程。

解决方法有三个:
1. 线程里面调用 pthread_detach(pthread_self()) 这个方法最简单
2. 在创建线程的设置PTHREAD_CREATE_DETACHED属性
3. 创建线程后用 pthread_join() 一直等待子线程结束。

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

void base() {
    //pritnf needs #include<stdio.h>
    printf("main\n");

    // pthread_t: unsigned long int
    pthread_t thread_id = pthread_self();
    printf("pthread_self(): %lu\n", thread_id);

    printf("getpid(): %d\n", getpid());
}

void *thread_func(void *args) {
    printf("%s thread pid:%d\n", __func__, getpid());
    int *temp;
    temp = (int *) args;
    printf("%s *args:%d\n", __func__, *temp);
    printf("%s Parent thread id:%lu\n", __func__, pthread_self());

   return NULL;
}

void testfork() {
    //pit_t int
    pid_t pid = fork();

    if (pid == 0) {
        printf("Child thread pid:%d\n", getpid());
        printf("Child thread id:%lu\n", pthread_self());

        pthread_t thread_pid;
        int temp = 10;
        pthread_create(&thread_pid, NULL, &thread_func, &temp);
        pthread_join(thread_pid, NULL);
        printf("Child thread pthread_create() thread_pid:%lu\n", thread_pid);
    } else if (pid > 0) {
        printf("Parent thread pid:%d\n", getpid());
        printf("Parent thread id:%lu\n", pthread_self());
    } else {
        printf("fork error.");
    }

    printf("Thread pid:%d\n", getpid());
    printf("Thread id:%lu\n", pthread_self());
}

void main(int argc, char **argv) {
    base();
    printf("\n");

    testfork();
    printf("\n");
}

 

posted @ 2015-04-18 15:53  牧 天  阅读(263)  评论(0)    收藏  举报