用Pthread实现多线程操作

学习Pthread时的笔记和demo,感谢各路大神的分享

pthread_create

#include 
#include 

void * thread(void *arg)
{
    printf("arg is %d.\n", *(int *)arg);
    *(int *)arg = 123456;
    return arg;
}

int main(int argc, char const *argv[])
{
    pthread_t tid;
    int arg = 111111;

    int res = pthread_create(&tid, NULL, thread, &arg);
    if (res != 0)
    {
        perror("pthread_create");
        return -1;
    }

    printf("main thread.\n");

    int *thread_res = NULL;
    res = pthread_join(tid, (void **)&thread_res);
    if (res != 0 || !thread_res)
    {
        perror("pthread_join");
        return -1;
    }

    printf("thread return val = %d\n", *thread_res);

    return 0;
}

复制代码

join detach

    线程的合并是一种主动回收线程资源的方案。当一个进程或线程调用了针对其它线程的pthread_join()接口,就是线程合并了。这个接口会阻塞调用进程或线程,直到被合并的线程结束为止。当被合并线程结束,pthread_join()接口就会回收这个线程的资源,并将这个线程的返回值返回给合并者。

    与线程合并相对应的另外一种线程资源回收机制是线程分离,调用接口是pthread_detach()。线程分离是将线程资源的回收工作交由系统自动来完成,也就是说当被分离的线程结束之后,系统会自动回收它的资源。因为线程分离是启动系统的自动回收机制,那么程序也就无法获得被分离线程的返回值,这就使得pthread_detach()接口只要拥有一个参数就行了,那就是被分离线程句柄。

    调用pthread_create()函数,线程要么是合并的(默认)要么是分离的。如果是合并属性的线程,那么必须使用pthread_join()等待结束,否则所占用的资源不会得到释放从而造成资源泄露。而分离属性的线程在结束的时候会自动释放所占用的资源。

    一个合并属性线程只能用一个pthread_join()函数来等待结束。如果有多个pthread_join函数则只有第一个执行到的有效,其他的都会直接返回错误。

detach demo

#include 
#include 

void * func(void *a)
{
    printf("other thread\n");
    return a;
}

int main(int argc, char *argv[])
{
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    
    //PTHREAD_CREATE_DETACHED(分离的)PTHREAD_CREATE_JOINABLE(可合并的,也是默认属性)
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    
    pthread_t th;
    pthread_create(&th, &attr, func, NULL);
    
    printf("main thread\n");
    
    pthread_attr_destroy(&attr);

    return 0;
}
复制代码

join demo

#include 
#include 
#include 

void * func(void *arg)
{
    int tid = (int)pthread_self();
    printf("tid %d start\n",tid);
    double result = 0.0;
    for (int i = 0;i < 100000;++i)
    {
        result += (double)random();
    }
    printf("tid %d result = %e\n",tid,result);
    printf("tid %d end\n",tid);
    
    return NULL;
}

int main(int argc, char const *argv[])
{
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    
    pthread_t thread[5];
    int len = sizeof(thread)/sizeof(pthread_t);
    
    for (int i = 0;i < len;++i)
    {
        int res = pthread_create(&thread[i], &attr, func, NULL);
        if (res != 0)
        {
            perror("pthread_create : ");
            exit(-1);
        }
    }

    pthread_attr_destroy(&attr);
    for (int i = 0;i < len;++i)
    {
        void *tres = NULL;
        int res = pthread_join(thread[i], &tres);
        if (res != 0)
        {
            perror("pthread_join : ");
            exit(-1);
        }
        printf("thread %d joined\n",i);
    }

    return 0;
}
复制代码

contention scope

#include 
#include 

void * start(void *a)
{
    return a;
}

int main(int argc, char const *argv[])
{
    pthread_attr_t attr;
    pthread_t th;
    
    pthread_attr_init(&attr);
    /*
     scope属性表示线程间竞争CPU的范围,也就是说线程优先级的有效范围。POSIX的标准中定义了两个值:PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争CPU时间,后者表示仅与同进程中的线程竞争CPU。
     */
    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
    pthread_create(&th, &attr, start, NULL);
    pthread_attr_destroy(&attr);
    
    return 0;
}
复制代码

lock

mutex lock

#include 
#include 
#include 
#include 
#include 

pthread_mutex_t mutex;
int sharedVar = 0;

void * func1(void *arg)
{
    time_t end = time(NULL) + 10;
    while(time(NULL) < end) 
    {
        int ret = pthread_mutex_trylock(&mutex);
        if(ret == EBUSY) 
        {
            printf("already lock\n");
        } 
        else if (ret == EINVAL) 
        {
            printf("lock is not init\n");
        }
        else if (ret == 0)
        {
            printf("thread 1 locked\n");
            ++sharedVar;
            pthread_mutex_unlock(&mutex);
        }
        sleep(1);
    }
    return NULL;
}

void * func2(void *arg)
{
    time_t end = time(NULL) + 10;
    while (time(NULL) < end) 
    {
        pthread_mutex_lock(&mutex);
        printf("thread 2 locked\n");
        ++sharedVar;
        sleep(1);
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_mutex_init(&mutex, NULL);
    
    pthread_t th1;    
    pthread_create(&th1, NULL, func1, NULL);
    pthread_t th2;
    pthread_create(&th2, NULL, func2, NULL);
    
    pthread_join(th1, NULL);
    pthread_join(th2, NULL);
    
    pthread_mutex_destroy(&mutex);
    printf("shared var = %d\n", sharedVar);
    
    return 0;
}
复制代码

condition lock

#include 
#include 
#include 

pthread_mutex_t mutex;
pthread_cond_t cond;

typedef struct 
{
    char buff[5];
    int count;
} buffer;

buffer sharedData = {.buff = "", .count = 0};
char ch = 'A';

void * producer(void *arg)
{
    printf("producer start\n");
    
    while (ch != 'Z') 
    {
        pthread_mutex_lock(&mutex);
        
        if (sharedData.count < 5) 
        {
            sharedData.buff[sharedData.count] = ch;
            printf("producer get char %c\n", ch);
            ch++;
            sharedData.count++;
            
            if (sharedData.count == 5) 
            {
                printf("producer signal\n");
                pthread_cond_signal(&cond);
            }
        }
        
        pthread_mutex_unlock(&mutex);
    }
    
    printf("producer end\n");
    return NULL;
}

void * consumer(void *arg)
{
    printf("consumer start\n");
    
    while (ch != 'Z') 
    {
        pthread_mutex_lock(&mutex);
        
        printf("consumer wait\n");
        pthread_cond_wait(&cond, &mutex);
        
        printf("consumer write\n");
        for (int i = 0; sharedData.buff[i] && sharedData.count; ++i) 
        {
            printf("%c",sharedData.buff[i]);
            --sharedData.count;
        }
        printf("\n");
        
        pthread_mutex_unlock(&mutex);
    }
    
    printf("consumer end\n");
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    
    pthread_t cth;
    pthread_create(&cth, NULL, consumer, NULL);
    pthread_t pth;
    pthread_create(&pth, NULL, producer, NULL);
    
    pthread_join(cth, NULL);
    pthread_join(pth, NULL);
    
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    
    return 0;
} 
复制代码

thread storage

#include 
#include 
#include 

pthread_key_t key;

typedef struct 
{
    int data;
} ThreadData;

void * func(void *arg)
{
    ThreadData *data = (ThreadData *)arg;
    printf("thread %d start\n", data->data);
    pthread_setspecific(key,data);
    printf("thread data is %d\n", ((ThreadData *)pthread_getspecific(key))->data);
    printf("thread %d exit\n", data->data);
    return arg;
}

void deconstruct(void *arg)
{
    printf("thread %d data free\n", ((ThreadData *)arg)->data);
    free(arg);
}

int main(int argc, char *argv[])
{
    pthread_t thread[5];
    size_t len = sizeof(thread)/sizeof(pthread_t);
    pthread_key_create(&key,deconstruct);
    
    for (int i = 0; i < len; ++i) 
    {
        ThreadData *threadData = (ThreadData *)malloc(sizeof(ThreadData));
        threadData->data = i;
        pthread_create(&thread[i], NULL, func, threadData);
    }
    
    for (int i = 0; i < len; ++i)
    {
        pthread_join(thread[i], NULL);
    }
    
    pthread_key_delete(key);
    return 0;
}
复制代码

你可能感兴趣的:(用Pthread实现多线程操作)