线程退出方式总结:
1.pthread_exit; void pthread_exit(void *retval);
传的是退出状态值对应的地址
2.执行函数中return
3.pthread_cancel // int pthread_cancel(pthread_t thread);
4.在任何一个线程中调用了exit
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
void * do_something(void *arg)
{
	static int a = 10;
	while (1)
	{
		//线程的任务函数 
		printf("------do_something ---- \n");
        sleep(1);
	}
	//pthread_exit(&a); //
	
	return &a; //线程执行函数中return
}
int main(int argc, const char *argv[])
{
	pthread_t tid;
	int ret = pthread_create(&tid,NULL,do_something,NULL);
	if (ret != 0)
	{
		errno = ret;
		perror("pthread_create fail");
		return -1;
	}
	sleep(3);
	pthread_cancel(tid); //取消线程
	printf("----cancel thread----\n");
#if 0
	void *retval; 
	pthread_join(tid,&retval);
	printf("---- main----%d\n",*(int *)retval);
#endif 
	pthread_exit(NULL);
	return 0;
} 
线程资源回收:
1.pthread_join //需要自己回收 线程的属性(可结合性)--一般是子线程在较短时间内 主线程需要关系子线程状态
2.pthread_detach //可分离属性:子线程运行很久才结束。主线程不需要关系子线程状态
int pthread_detach(pthread_t thread);
 功能:分离线程
参数:要分离的线程tid
返回值:成功0;失败错误码。
线程和进程的对比
1.线程 CPU执行的最小单位 
  进程 资源分配和任务调度基本单位 
2.安全性
线程 
 好处:共享了进程的数据空间 ,共享数据方面 方便 
 缺点: 安全性不好会带来资源竞争           
 进程   进程空间相互独立 
 优点:
 安全性好 
 缺点:
 进程间共享数据不方便      //进程间通信   (管道,信号,共享内存)
主要区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。
锁:
机制:互斥锁
互斥:要么不访问,要访问就是一次完整操作(原子操作)

定义锁 pthread_mutex_t mutex;
初始化锁 pthread_mutex_init;
加锁 int pthread_mutex_lock(pthread_mutex_t *mutex);
解锁 int pthread_mutex_unlock(pthread_mutex_t *mutex);
销毁锁 pthread_mutex_destory(pthread_mutex_t *mutex);
teylock 和 lock的区别:
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
void* increment_counter(void* arg) {
    for (int i = 0; i < 10000; ++i) {
        // 锁定互斥锁,等待直到获得锁
        pthread_mutex_lock(&mutex);
        // 安全地更新计数器
        counter++;
        printf("Counter is now %d\n", counter);
        // 释放互斥锁
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}
int main() {
    pthread_t t1, t2;
    // 创建两个线程
    pthread_create(&t1, NULL, increment_counter, NULL);
    pthread_create(&t2, NULL, increment_counter, NULL);
    // 等待线程结束
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    printf("Final counter value is %d\n", counter);
    return 0;
} 
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
void* increment_counter_trylock(void* arg) {
    for (int i = 0; i < 10000; ++i) {
        // 尝试锁定互斥锁
        if (pthread_mutex_trylock(&mutex) == 0) {
            // 成功获取锁,更新计数器
            counter++;
            printf("Counter is now %d\n", counter);
            // 释放互斥锁
            pthread_mutex_unlock(&mutex);
        } else {
            // 未能获取锁,可以做一些其他的事情或者简单地重试
            // 这里我们选择简单的重试
            continue;
        }
    }
    return NULL;
}
int main() {
    pthread_t t1, t2;
    // 创建两个线程
    pthread_create(&t1, NULL, increment_counter_trylock, NULL);
    pthread_create(&t2, NULL, increment_counter_trylock, NULL);
    // 等待线程结束
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    printf("Final counter value is %d\n", counter);
    return 0;
} 
死锁

线程间的顺序问题: 同步操作 
 信号量:实现一种可以让线程间有序访问临界资源的方式, 可以顺序操作的一把锁



















