Linux Programing -- ch12-- POSIX 线程

来源:互联网 发布:全球网络卫星电视直播 编辑:程序博客网 时间:2024/05/20 05:06

1. 无题

在linux 2.6以前, pthread线程库对应的实现是一个名叫linuxthreads的lib. linuxthreads利用前面提到的轻量级进程来实现线程。
到了linux 2.6, glibc中有了一种新的pthread线程库NPTL(Native POSIX Threading Library). NPTL实现了前面提到的POSIX的全部5点要求. 但是, 实际上, 与其说是NPTL实现了, 不如说是linux内核实现了.在linux 2.6中, 内核有了线程组的概念, task_struct结构中增加了一个tgid(thread group id)字段. 如果这个task是一个”主线程”, 则它的tgid等于pid, 否则tgid等于进程的pid(即主线程的pid),此外,每个线程有自己的pid。

2. API

#include <pthread.h>int pthread_create(pthread_t *thread, pthread_attr_t * attr, void*(*start_routine)(void *), void *arg);void pthread_exit(void *retval);int pthread_join(pthread_t thread, void **thread_return)

例程:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <pthread.h>void *thread_function(void *arg);char message[] = "hello word";int main(int argc, char *argv[]){    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 jion failed\n");        exit(EXIT_FAILURE);    }    printf("Thead joined, it return %s\n", (char*)thread_result);    printf("Message now is %s\n", message);    exit(EXIT_SUCCESS);}void *thread_function(void *arg){    printf("thread_fuction is runing...argument is %s\n", (char*)arg);    sleep(5);    strcpy(message, "Bye!");    pthread_exit("Thank you for your cup tiome\n");}

3. 线程同步–信号量

#include <semaphore.h>int sem_int(sem_t *sem, int pshared, unsigned int value); // pshare 用于进程间共享, linux 暂不支持,值为0int sem_wait(sem_t *sem);int sem_post(sem_t * sem);int sem_destroy((sem_t *sem);

post 操作给信号量加 1,wait 操作给信号量减 1 但是他会阻塞知道信号量有个非零值才做减法操作。
sem_trywaitsem_wait的非阻塞版本。

例程:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>sem_t sem;void *thread_function(void *arg);#define WORK_SIZE 1024char work_area[WORK_SIZE];int main(int argc, char *argv[]){    int res;    pthread_t a_thread;    void *thread_result;    res = sem_init(&sem, 0, 0);    if(res != 0){        perror("Init semaphore failed\n");        exit(EXIT_FAILURE);    }    res = pthread_create(&a_thread, NULL, thread_function, NULL);    if(res != 0){        perror("Create thread failed\n");        exit(EXIT_FAILURE);    }    printf("Input some text. Enter 'end' to finish..\n");    while(strncmp("end", work_area, 3) != 0){        fgets(work_area, WORK_SIZE, stdin);        sem_post(&sem);    }    printf("Waiting for the thread to finish...\n");    res = pthread_join(a_thread, &thread_result);    if(res != 0){        perror("thread join failed\n");        exit(EXIT_FAILURE);    }    printf("Thread joined\n");    sem_destroy(&sem);    exit(EXIT_SUCCESS);}void *thread_function(void *arg){    sem_wait(&sem);    while(strncmp("end", work_area, 3) != 0){        printf("you input %d characters\n", strlen(work_area) - 1);        sem_wait(&sem);    }    pthread_exit(NULL);}

在上面的例程中有一个问题,假设计算字符个数的线程运行速度比主线程慢(可以在线程中加入一段 sleep),那么久会出现字符还没被计算出来字符数组 work_area 的内容就被改变了,也就是说这时候的限号量大于 1 了。

4. 线程同步–互斥量

#include <pthread.h>int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);int phtread_mutex_lock(pthread_mutex_t *mutex);int phtread_mutex_unlock(pthread_mutex_t *mutex);int pthread_mutex_destroy(phtread_mutex_t *mutex);

5.线程属性

#include <pthread.h>int pthread_attr_init(pthread_attr_t *attr);int pthread_attr_destroy(pthread_attr_t *attr);int pthread_attr_setdetachstate(pthread_attr_t * attr, int detachstate);int pthread_attr_getdetachstate(phtread_attr_t *attr,, int *detachstate);int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);int pthread_attr_setschedparam(pthread_attr_t  * attr,  const struct sched_param *param);int pthread_attr_getschedparam(const pthread_attr_t  * attr,  const struct sched_param *param);int pthread_attr_setinheritsched(pthread_attr_t   *attr, int inherit);int pthread_attr_getinheritsched(const pthread_attr_t   *attr, int *inherit);int pthread_attr_setscope(pthread_attr_t  *attr, int scope);int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);int pthread_attr_setstacksize(pthread_attr_t *attr, int size);int pthread_attr_setstacksize(const pthread_attr_t *attr, int *size);

6. 取消线程

#include <.pthread.h>int pthread_cancel(pthread_t thread);
#include <.pthread.h>int pthread_setcancelstate(in state, int *oldstate); 

PTHREAD_CANCEL_ENABLE
PTHREAD_CANCEL_DISABLE

#include <.pthread.h>int pthread_stecanceltype(int state, int *oldstate);

PTHREAD_CANCEL_ASYNCHRONOUS
PTHREAD_CANCEL_DEFERRED

7. 没了

线程的知识很多,这里做个粗略的总结

0 0