fengjing81 2020-05-08
如果进程结束,进程下的所有线程都会被结束
#include <pthread.h> int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(routine)(void *),void *arg); // 成功返回0 // 失败返回错误码 // tread线程对象 // attr 线程属性,NULL代表默认属性 // *(routine)(void *) routine线程执行的函数 // arg传递给现场执行函数的参数
#include <pthread.h> int pthread_join(pthread_t thread,void **retval); // 成功返回0 // 失败时返回错误码 // thread 要回收的线程对象 // *retval 接受线程thread的返回值 // 调用线程阻塞知道thread的返回值
#include <pthread.h> void pthread_exit(void *retval); // 结束当前线程 或指定到函数的return结束 // retval可被其他线程通过pthread_join获取 // retval不能是局部变量否则会出错 // 线程私有资源被释放
Demo:
#include <pthread.h>
#include <stdio.h>
#include <zconf.h>
#include <string.h>
char message[32] = "hello World";
void *thread_func(void *arg) {
    sleep(1);
    strcpy(message, "thread hello");
    // 线程退出
    // pthread_exit("thread over");
    return "thread over"; // 与上方pthread_exit效果相同
}
int main(int argc, char *argv[]) {
    pthread_t a_thread;
    void *result;
    // 创建线程
    if (pthread_create(&a_thread, NULL, thread_func, NULL) != 0) {
        perror("pthread_create");
    }
    // 线程回收
    pthread_join(a_thread, &result);
    printf("result:%s\n", result); // result接受线程的返回值
    // 查看线程是否继承了进程的资源
    printf("message:%s\n", message);
    return 0;
}
// Ps:编译一定要链接 否则会报错
// $gcc -o test test.c -l pthread同步(synchronization)指的是多个任务按照约定的先后次序相互配合完成一件事
由信号量来决定线程是继续运行还是阻塞等待
if (信号量的值大于0){申请资源的任务继续运行;信号量的值减一;}
else{申请资源的任务阻塞;}if(有任务在等待资源){唤醒等待任务,让其继续运行}#include <semaphore.h> int sem_init(sem_t *sem,int pshared,unsigned int val); // 信号量被创建后必须初始化 // 成功时返回0 // 失败返回EOF // sem 指向要初始化的信号量对象 // pshared 信号量的使用范围 0代表线程间 1代表进程间 // val信号量的初值,0代表没有资源,大于0代表有资源
#include <semaphore.h> int sem_wait(sem_t *sem); // P操作 int sem_post(sem_t *sem); // V操作 // 成功时返回0 // 失败时返回EOF // sem执行要操作的信号量对象
Demo1:两个线程同步读写缓冲区(生产者、消费者问题)
#include <pthread.h>
#include <stdio.h>
#include <zconf.h>
#include <string.h>
#include <semaphore.h>
// 全局buf
char buf[32];
sem_t ser;
sem_t sew;
void *function(void *args) {
    while (1) {
        // 执行p操作
        sem_wait(&ser);
        printf("you enter %d charachtes\n", strlen(buf));
        sem_post(&sew);
    }
};
int main(int argc, char *argv[]) {
    pthread_t a_thread;
    // 先初始化信号量 写和读
    if (sem_init(&ser, 0, 0) < 0) {
        perror("sem_init");
        return 0;
    }
    // 这里初始化为1
    if (sem_init(&sew, 0, 1) < 0) {
        perror("sem_init");
        return 0;
    }
    // 再创建线程
    if (pthread_create(&a_thread, NULL, function, NULL) != 0) {
        printf("no create");
        return 0;
    }
    printf("input quit to exit:\n");
    do {
        // 每次往缓冲区写完一次操作后都将执行一次post v操作操作
        sem_wait(&sew);
        fgets(buf, 32, stdin);
        sem_post(&ser);
    } while (strncmp(buf, "quit", 4) != 0);
    {
        // 如果输入不是quit则继续循环
        return 0;
    }
}#include <pthread.h> int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *attr); // 成功时返回0 // 失败时返回错误码 // mutex 指向要初始化的互斥锁对象 // attr互斥锁属性,NULL表示缺省属性
#include <pthread.h> int pthread_mutex_lock(pthread_mutex_t * mutex); // 成功时返回0 // 失败时返回错误码 // 如果无法获得锁,任务阻塞 // mutex 指向要初始化的互斥锁对象
#include <pthread.h> int pthread_mutex_unlock(pthread_mutex_t *mutex); // 成功时返回0 // 失败时返回错误码 // 执行完临界区要即使释放 // mutex指向要初始化的互斥锁对象
Demo:
#include <pthread.h>
#include <stdio.h>
#include <zconf.h>
unsigned int value1, value2;
pthread_mutex_t lock;
int number = 0;
void *function() {
    pthread_mutex_lock(&lock);
    puts("子线程进入");
    value1 = number++;
    value2 = ++number;
    sleep(1);
    puts("子线程截止");
    printf("value1: %d value2:%d\n", value1, value2);
    pthread_mutex_unlock(&lock);
    return 0;
}
int main(int argc, char *argv[]) {
    pthread_t a_thread;
    // 初始化锁
    if (pthread_mutex_init(&lock, NULL) != 0) {
        perror("pthread_mutex_init");
        return 0;
    }
    // 创建线程
    if (pthread_create(&a_thread, NULL, function, NULL) != 0) {
        perror("pthread_create");
        return 0;
    }
    // 加锁
    pthread_mutex_lock(&lock);
    puts("主进程进入");
    value1 = number++;
    value2 = ++number;
    sleep(1);
    puts("主进程截止");
    printf("value1: %d value2:%d\n", value1, value2);
    pthread_mutex_unlock(&lock);
    sleep(3);
}