Linux Programing -- ch12-- POSIX 线程

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 暂不支持,值为0
int 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 1024
char 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. 没了

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值