深圳专门做网站的公司有哪些,网页版梦幻西游金色什么伙伴比较好,高端ppt模板,在线域名解析ip地址文章目录 线程的概念线程与进程 线程的用法线程的创建多线程 线程的等待线程锁死锁 线程的概念 在Linux中#xff0c;线程#xff08;Thread#xff09;是程序执行流的最小单位#xff0c;是进程中的一个实体#xff0c;负责在程序中执行代码。线程本身不拥有系统资源线程Thread是程序执行流的最小单位是进程中的一个实体负责在程序中执行代码。线程本身不拥有系统资源但它可以访问其所属进程的资源包括内存空间、文件句柄等。线程与进程的主要区别在于线程是共享进程资源的而进程之间则是独立的。 线程与进程 在Linux中线程有时被称为轻量级进程Lightweight Process, LWP。从内核的角度来看线程和进程在很大程度上是相似的它们都通过task_struct结构体来描述。但是线程与父进程或其他线程共享某些资源如地址空间和文件描述符表而进程则拥有自己的独立资源。 PCBProcess Control Block即进程控制块。 虽然线程和进程都使用task_struct来描述但Linux内核通过一些特定的字段来区分它们。例如每个task_struct都有一个pid进程ID和一个tgid线程组ID。对于主线程也就是我们通常所说的“进程”其pid和tgid是相同的。但是对于该进程创建的其他线程它们的pid是唯一的但tgid与主线程的tgid也就是该进程的ID相同。通过这种方式内核可以区分一个task_struct描述的是进程还是线程。 进程与线程关系图 波浪线代表一个线程
线程的用法
线程的创建
需要pthread_creart函数来创建线程。
#include iostream
#include unistd.h
#include pthread.h
void *ThreadRoutine(void *args)
{const char *threadname (const char *)args;while (true){std::cout i am a new: threadname std::endl;sleep(1);}
}
int main()
{pthread_t tid;pthread_create(tid, nullptr, ThreadRoutine, (void *)thread 1);while(true){std:: cout i am main thread std::endl;sleep(1);}return 0;
}看图可以得知我们创建了一个线程主线程仍然在继续运行。
多线程
void *ThreadRoutine(void *args)
{const char *threadname (const char *)args;while (true){std::cout i am a new: threadname std::endl;sleep(3);}
}
int main()
{pthread_t tid1;pthread_create(tid1, nullptr, ThreadRoutine, (void *)thread 1);sleep(3);pthread_t tid2;pthread_create(tid2, nullptr, ThreadRoutine, (void *)thread 2);sleep(3);pthread_t tid3;pthread_create(tid3, nullptr, ThreadRoutine, (void *)thread 3);sleep(3);pthread_t tid4;pthread_create(tid4, nullptr, ThreadRoutine, (void *)thread 4);sleep(3);while (true){std::cout i am main thread std::endl;sleep(3);}return 0;
}可以看出线程2,3,4都正常运行。
线程的等待 pthread_t thread这是你想要等待的线程的标识符。这个标识符是在调用pthread_create时返回的。 **void retval这是一个指向指针的指针用于获取被等待线程的返回值。如果retval不是NULL那么pthread_join会将终止线程的返回值放在*retval所指向的位置。如果你对线程的返回值不感兴趣可以将这个参数设置为NULL。
#include iostream
#include unistd.h
#include pthread.h
void *ThreadRoutine(void *args)
{int cnt 5;const char *threadname (const char *)args;while (cnt){std::cout i am a new: threadname std::endl;sleep(1);cnt--;}return args;
}
int main()
{pthread_t tid1;pthread_create(tid1, nullptr, ThreadRoutine, (void *)thread 1);void *ret nullptr;pthread_join(tid1,ret);std:: cout (char *)ret std::endl;sleep(3);//while ()//{std::cout i am main thread std::endl;sleep(1);//}return 0;
}在函数体内我们将args作为返回值可以看到将函数的返回值通过pthread_join()函数传送到ret这个指针上.
线程锁 线程锁Thread Lock是一种同步机制主要用于解决多线程访问共享资源时可能出现的并发问题。 #include iostream
#include unistd.h
#include pthread.h
int ticket 10000;
void *ThreadRoutine(void *args)
{const char *threadname (const char *)args;while (ticket 0){std::cout i am : threadname getticket: ticket-- std::endl;}return args;
}
int main()
{pthread_t tid1;pthread_create(tid1, nullptr, ThreadRoutine, (void *)thread 1);pthread_t tid2;pthread_create(tid2, nullptr, ThreadRoutine, (void *)thread 2);pthread_t tid3;pthread_create(tid3, nullptr, ThreadRoutine, (void *)thread 3);pthread_t tid4;pthread_create(tid4, nullptr, ThreadRoutine, (void *)thread 4);void *ret1 nullptr;void *ret2 nullptr;void *ret3 nullptr;void *ret4 nullptr;pthread_join(tid1, ret1);pthread_join(tid2, ret2);pthread_join(tid3, ret3);pthread_join(tid4, ret4);std::cout i am main thread,Finish std::endl;return 0;
}如以上代码我们模拟一个多个线程抢车票的的进程。代码中设计当车票为零时则退出while循环并且退出函数退出线程。 但经过我们多次试验发现图下现象 票数竟会变成负数 假设ticket值为1当一个线程已经进入while循环内但对于ticket值并没有做出改变此时另一个线程就会用相同的ticket值也进入了while循环两个进程又都进行了减减操作导致ticket值变为-1. 这时就要用上锁来保证多线程防止同时访问共享资源。 代码实现
#include iostream
#include unistd.h
#include pthread.h
int ticket 10000;
pthread_mutex_t lock;//全局锁
void *ThreadRoutine(void *args)
{const char *threadname (const char *)args;pthread_mutex_lock(lock);//上锁while (ticket 0){std::cout i am : threadname getticket: ticket-- std::endl;}pthread_mutex_unlock(lock);//解锁return args;
}
int main()
{pthread_mutex_init(lock, nullptr);pthread_t tid1;pthread_create(tid1, nullptr, ThreadRoutine, (void *)thread 1);pthread_t tid2;pthread_create(tid2, nullptr, ThreadRoutine, (void *)thread 2);pthread_t tid3;pthread_create(tid3, nullptr, ThreadRoutine, (void *)thread 3);pthread_t tid4;pthread_create(tid4, nullptr, ThreadRoutine, (void *)thread 4);void *ret1 nullptr;void *ret2 nullptr;void *ret3 nullptr;void *ret4 nullptr;pthread_join(tid1, ret1);pthread_join(tid2, ret2);pthread_join(tid3, ret3);pthread_join(tid4, ret4);std::cout i am main thread,Finish std::endl;return 0;
}通过给区间上锁来防止多线程同时访问资源。
死锁 如上图,线程A线程B倘若线程A中申请到了LOCK1而线程B中申请到了LOCK2线程A等待LOCK2的释放线程B等待LOCK1的释放就会导致互相等待两个线程都进行不下去导致死锁 如何避免 避免嵌套锁尽量不在持有锁的同时请求另一个锁。如果必须这样做确保加锁的顺序在所有线程中都是一致的。 保持锁的顺序一致多个线程在尝试获取多个锁时总是以相同的顺序请求它们。这可以防止循环等待条件的发生即线程A等待线程B释放锁而线程B又在等待线程A释放另一个锁。 使用超时机制在尝试获取锁时设置超时。如果线程不能在规定的时间内获得锁它将放弃并稍后重试。这可以防止线程无限期地等待从而增加了系统的灵活性。 减少锁的粒度尽量只锁定需要保护的最小资源范围。例如如果你可以只锁定一个数据结构的一部分而不是整个数据结构那么这将减少死锁的可能性。 避免长时间持有锁尽量缩短持有锁的时间。这意味着你应该在获得锁后尽快完成你的工作并释放锁。