POSIX多线程

线程的建立和使用

pthread_t thread; // 声明线程变量

int pthread_create(pthread_t thread, const pthread_attr_t attr, void *args) // 创建线程并且运行

pthread_t pthread_self(); //获取当前的线程

int pthread_exit(void *value_str); // 退出线程

int pthread_detach(pthread_t thread); //分离线程

int pthread_join(pthread_t thread, void **value_str) //等待线程终止

示例:

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

void* func(void *args) {
    char *s = (char*) args;
    printf("args = %s\n", s);
    printf(">>> thread run >>\n");
    pthread_t thread = pthread_self(); // 获取pid
    printf("pid = %d\n", thread);
    return thread;
}

int main() {
    pthread_t thread;
    char *str = "hello world"; // 传递参数
    pthread_create(&thread, NULL, func, (void*) str);
    void *res_val;  // 接受线程返回的结果
    pthread_join(thread, &res_val);
    printf("result value = %d\n", (int) res_val);
    pthread_exit(&thread);
    return 0;
}

output:

args = hello world
>>> thread run >>
pid = 1
result value = 1

同步

使用线程编写各种程序,都需要在线程键共享数据或者需要以一致的顺序在线程间执行一组操作。为了实现该目标,需要同步线程的各种操作。

pthread_mutex_t mutex

int pthread_mutex_init(pthread_mutex_t mutex, pthread_mutex_attr_t attr)

int pthread_mutex_destory(pthread_mutex_t *mutex)

int pthread_mutex_lock(pthread_mutex_t *mutex)

int pthread_mutex_try_lock(pthread_mutex_t *mutex)

int pthread_mutex_unlock(pthread_mutex_t *mutex)

示例:

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

int count = 0;
pthread_mutex_t mutex;

void* increment(){
    //加锁
    pthread_mutex_lock(&mutex);
    count++;
    pthread_t thread = pthread_self();
    printf("pid = %d, count = %d\n", thread, count);
    // 解锁
    pthread_mutex_unlock(&mutex);
    sleep(1);
    return NULL;
}

int main() {
    // 初始化 mutex
    pthread_mutex_init(&mutex, NULL); 
    pthread_t thread[1000];
    for(int i=0; i<1000; i++){
        pthread_create(&thread[i], NULL, increment, NULL);
    }
    // 5s 等待线程执行完成
    sleep(5);
    return 0;
}

output:

pid = 3, count = 1
pid = 4, count = 2
pid = 1, count = 3

.....

pid = 997, count = 997
pid = 998, count = 998
pid = 999, count = 999
pid = 1000, count = 1000

条件变量

pthread_cond_t cond

pthread_cond_init(ppthread_cond_t cond, pthread_condattr_t condattr)

int pthread_cond_destroy(pthread_cond_t *cond)

int pthread_cond_wait(pthread_cond_t cond, pthread_mutex_t mutex)

int pthread_cond_timedwait(pthread_cond_t cond, pthread_mutex_t mutex, struct timespec *expiration)

int pthread_cond_signal(pthread_cond_t *cond)

int pthread_cond_broadcast(pthread_cond_t *cond)

生产者与消费者示例:

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

int token = 2;
#define N 5
pthread_cond_t empty;
pthread_cond_t full;
pthread_mutex_t mutex;
void worka(void *args) {
    while (1) {
        pthread_mutex_lock(&mutex);
        while (token == N) {
            pthread_cond_wait(&full, &mutex);
        }
        token++;
        int pid = pthread_self();
        printf("producer = %d, token=%d\n", pid, token);
        pthread_cond_signal(&empty);
        pthread_mutex_unlock(&mutex);
    }
}

void workb(void *args) {
    while (1) {
        pthread_mutex_lock(&mutex);
        while (token == 0) {
            pthread_cond_wait(&empty, &mutex);
        }
        token--;
        int pid = pthread_self();
        printf("consumer = %d, token = %d\n", pid, token);
        pthread_cond_signal(&full);
        pthread_mutex_unlock(&mutex);
    }
}

int main(){
    setbuf(stdout, NULL); // 取消缓冲行
    pthread_cond_init(&empty, NULL);
    pthread_cond_init(&full, NULL);
    pthread_mutex_init(&mutex, NULL);
    pthread_t producer, consumer;
    pthread_create(&producer, NULL, worka, NULL);
    pthread_create(&consumer, NULL, workb, NULL);

    pthread_join(producer, NULL);
    pthread_join(consumer, NULL);
}

output:

......
consumer = 2, token = 4
consumer = 2, token = 3
consumer = 2, token = 2
consumer = 2, token = 1
consumer = 2, token = 0
producer = 1, token=1
producer = 1, token=2
producer = 1, token=3
producer = 1, token=4
producer = 1, token=5
.....
添加新评论