- 获取线程号
- #include
- pthread_t pthread_self(void);
- 成功:返回线程号
测试例程 1
- #include
- #include
-
- int main()
- {
- pthread_t tid = pthread_self();
- printf("tid = %lu\n",(unsigned long)tid);
- return 0;
- }
编译结果:
![]()
怎么创建线程呢?使用 pthread_create 函数:
- 创建线程
- #include
- int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
- #include
- #include
- #include
- #include
-
- void *fun(void *arg)
- {
- printf("pthread_New = %lu\n",(unsigned long)pthread_self());
- }
-
- int main()
- {
-
- pthread_t tid1;
- int ret = pthread_create(&tid1,NULL,fun,NULL);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
-
- /*tid_main 为通过pthread_self获取的线程ID,tid_new通过执行pthread_create成功后tid指向的空间*/
- printf("tid_main = %lu tid_new = %lu \n",(unsigned long)pthread_self(),(unsigned long)tid1);
-
- /*因线程执行顺序随机,不加sleep可能导致猪线程先执行,导致进程结束,无法执行到子线程*/
- sleep(1);
-
- return 0;
- }

![]()
- #include
- #include
- #include
- #include
-
- void *fun1(void *arg)
- {
- printf("%s:arg = %d Addr = %p\n",__FUNCTION__,*(int *)arg,arg);
- }
-
- void *fun2(void *arg)
- {
- printf("%s:arg = %d Addr = %p\n",__FUNCTION__,(int)(long)arg,arg);
- }
-
- int main()
- {
-
- pthread_t tid1,tid2;
- int a = 50;
- int ret = pthread_create(&tid1,NULL,fun1,(void *)&a);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- ret = pthread_create(&tid2,NULL,fun2,(void *)(long)a);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- sleep(1);
- printf("%s:a = %d Add = %p \n",__FUNCTION__,a,&a);
- return 0;
- }

测试例程 4:
- #include
- #include
- #include
- #include
-
- void *fun1(void *arg)
- {
- while(1){
-
- printf("%s:arg = %d Addr = %p\n",__FUNCTION__,*(int *)arg,arg);
- sleep(1);
- }
- }
-
- void *fun2(void *arg)
- {
- while(1){
-
- printf("%s:arg = %d Addr = %p\n",__FUNCTION__,(int)(long)arg,arg);
- sleep(1);
- }
- }
-
- int main()
- {
-
- pthread_t tid1,tid2;
- int a = 50;
- int ret = pthread_create(&tid1,NULL,fun1,(void *)&a);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- sleep(1);
- ret = pthread_create(&tid2,NULL,fun2,(void *)(long)a);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- while(1){
- a++;
- sleep(1);
- printf("%s:a = %d Add = %p \n",__FUNCTION__,a,&a);
- }
- return 0;
- }
运行结果:

- #include
- #include
- #include
- #include
- #include
-
- struct Stu{
- int Id;
- char Name[32];
- float Mark;
- };
-
- void *fun1(void *arg)
- {
- struct Stu *tmp = (struct Stu *)arg;
- printf("%s:Id = %d Name = %s Mark = %.2f\n",__FUNCTION__,tmp->Id,tmp->Name,tmp->Mark);
-
- }
-
- int main()
- {
-
- pthread_t tid1,tid2;
- struct Stu stu;
- stu.Id = 10000;
- strcpy(stu.Name,"ZhangSan");
- stu.Mark = 94.6;
-
- int ret = pthread_create(&tid1,NULL,fun1,(void *)&stu);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- printf("%s:Id = %d Name = %s Mark = %.2f\n",__FUNCTION__,stu.Id,stu.Name,stu.Mark);
- sleep(1);
- return 0;
- }

- 线程主动退出
- #include
- void pthread_exit(void *retval);
- 线程被动退出,其他线程使用该函数让另一个线程退出
- #include
- int pthread_cancel(pthread_t thread);
- 成功:返回 0
- 线程资源回收(阻塞)
- #include
- int pthread_join(pthread_t thread, void **retval);
该函数为线程回收函数,默认状态为阻塞状态,直到成功回收线程后才返回。第一个参数为要回收线程的 tid 号,第二个参数为线程回收后接受线程传出的数据。
- 线程资源回收(非阻塞)
- #define _GNU_SOURCE
- #include
- int pthread_tryjoin_np(pthread_t thread, void **retval);
测试例程 6:
- #include
- #include
- #include
- #include
-
- void *fun1(void *arg)
- {
- static int tmp = 0;//必须要static修饰,否则pthread_join无法获取到正确值
- //int tmp = 0;
- tmp = *(int *)arg;
- tmp+=100;
- printf("%s:Addr = %p tmp = %d\n",__FUNCTION__,&tmp,tmp);
- pthread_exit((void *)&tmp);
- }
-
-
- int main()
- {
-
- pthread_t tid1;
- int a = 50;
- void *Tmp = NULL;
- int ret = pthread_create(&tid1,NULL,fun1,(void *)&a);//将变量以地址的形式传入线程,在线程中做出了自加100 的操作
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- pthread_join(tid1,&Tmp);
- printf("%s:Addr = %p Val = %d\n",__FUNCTION__,Tmp,*(int *)Tmp);
- return 0;
- }

- #include
- #include
- #include
- #include
- #include
-
- struct Stu{
- int Id;
- char Name[32];
- float Mark;
- };
-
- void *fun1(void *arg)
- {
- struct Stu *tmp = (struct Stu *)arg;
- printf("%s:Id = %d Name = %s Mark = %.2f\n",__FUNCTION__,tmp->Id,tmp->Name,tmp->Mark);
-
- }
-
- int main()
- {
-
- pthread_t tid1,tid2;
- struct Stu stu;
- stu.Id = 10000;
- strcpy(stu.Name,"ZhangSan");
- stu.Mark = 94.6;
-
- int ret = pthread_create(&tid1,NULL,fun1,(void *)&stu);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- printf("%s:Id = %d Name = %s Mark = %.2f\n",__FUNCTION__,stu.Id,stu.Name,stu.Mark);
- sleep(1);
- return 0;
- }

- #define _GNU_SOURCE
- #include
- #include
- #include
- #include
-
- void *fun1(void *arg)
- {
- printf("Pthread:1 come!\n");
- while(1){
- sleep(1);
- }
- }
-
- void *fun2(void *arg)
- {
- printf("Pthread:2 come!\n");
- pthread_cancel((pthread_t )(long)arg);
- pthread_exit(NULL);
- }
-
- int main()
- {
- int ret,i,flag = 0;
- void *Tmp = NULL;
- pthread_t tid[2];
- ret = pthread_create(&tid[0],NULL,fun1,NULL);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- sleep(1);
- ret = pthread_create(&tid[1],NULL,fun2,(void *)tid[0]);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- while(1){
- for(i = 0;i <2;i++){
- if(pthread_tryjoin_np(tid[i],NULL) == 0){
- printf("Pthread : %d exit !\n",i+1);
- flag++;
- }
- }
- if(flag >= 2) break;
- }
- return 0;
- }

- #define _GNU_SOURCE
- #include
- #include
- #include
- #include
-
-
- int Num = 0;
-
- void *fun1(void *arg)
- {
- while(Num < 3){
- Num++;
- printf("%s:Num = %d\n",__FUNCTION__,Num);
- sleep(1);
- }
- pthread_exit(NULL);
- }
-
- void *fun2(void *arg)
- {
- while(Num > -3){
- Num--;
- printf("%s:Num = %d\n",__FUNCTION__,Num);
- sleep(1);
- }
- pthread_exit(NULL);
- }
-
- int main()
- {
- int ret;
- pthread_t tid1,tid2;
- ret = pthread_create(&tid1,NULL,fun1,NULL);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- ret = pthread_create(&tid2,NULL,fun2,NULL);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- pthread_join(tid1,NULL);
- pthread_join(tid2,NULL);
- return 0;
- }

int pthread_mutex_init(phtread_mutex_t *mutex, const pthread_mutexattr_t *restrict attr)
pthread_mutex_t mutex = PTHREAD_MUTEX_INITALIZER;
- 互斥量加锁(阻塞)/解锁
- #include
- int pthread_mutex_lock(pthread_mutex_t *mutex);
- int pthread_mutex_unlock(pthread_mutex_t *mutex);
- 成功:返回 0
- 互斥量加锁(非阻塞)
- #include
- int pthread_mutex_trylock(pthread_mutex_t *mutex);
- 互斥量销毁
- #include
- int pthread_mutex_destory(pthread_mutex_t *mutex);
- 成功:返回 0
- #define _GNU_SOURCE
- #include
- #include
- #include
- #include
-
- pthread_mutex_t mutex;//互斥量变量 一般申请全局变量
-
- int Num = 0;//公共临界变量
-
- void *fun1(void *arg)
- {
- pthread_mutex_lock(&mutex);//加锁 若有线程获得锁,则会阻塞
- while(Num < 3){
- Num++;
- printf("%s:Num = %d\n",__FUNCTION__,Num);
- sleep(1);
- }
- pthread_mutex_unlock(&mutex);//解锁
- pthread_exit(NULL);//线程退出 pthread_join 会回收资源
- }
-
- void *fun2(void *arg)
- {
- pthread_mutex_lock(&mutex);加锁 若有线程获得锁,则会阻塞
- while(Num > -3){
- Num--;
- printf("%s:Num = %d\n",__FUNCTION__,Num);
- sleep(1);
- }
- pthread_mutex_unlock(&mutex);//解锁
- pthread_exit(NULL);//线程退出 pthread_join 会回收资源
- }
-
- int main()
- {
- int ret;
- pthread_t tid1,tid2;
- ret = pthread_mutex_init(&mutex,NULL);//初始化互斥量
- if(ret != 0){
- perror("pthread_mutex_init");
- return -1;
- }
- ret = pthread_create(&tid1,NULL,fun1,NULL);//创建线程 1
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- ret = pthread_create(&tid2,NULL,fun2,NULL);//创建线程 2
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- pthread_join(tid1,NULL);//阻塞回收线程 1
- pthread_join(tid2,NULL);//阻塞回收线程 2
- pthread_mutex_destroy(&mutex);//销毁互斥量
- return 0;
- }
- #define _GNU_SOURCE
- #include
- #include
- #include
- #include
-
- void *fun1(void *arg)
- {
- printf("%s:Pthread Come!\n",__FUNCTION__);
- pthread_exit(NULL);
- }
-
- void *fun2(void *arg)
- {
- printf("%s:Pthread Come!\n",__FUNCTION__);
- pthread_exit(NULL);
- }
-
- void *fun3(void *arg)
- {
- printf("%s:Pthread Come!\n",__FUNCTION__);
- pthread_exit(NULL);
- }
-
- int main()
- {
- int ret;
- pthread_t tid1,tid2,tid3;
- ret = pthread_create(&tid1,NULL,fun1,NULL);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- ret = pthread_create(&tid2,NULL,fun2,NULL);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- ret = pthread_create(&tid3,NULL,fun3,NULL);
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- pthread_join(tid1,NULL);
- pthread_join(tid2,NULL);
- pthread_join(tid3,NULL);
- return 0;
- }

注意:信号量跟互斥量不一样,互斥量用来防止多个线程同时访问某个临界资源。信号量起通知作用,线程 A 在等待某件事,线程 B 完成了这件事后就可以给线程 A 发信号。
int sem_init(sem_t *sem,int pshared,unsigned int value);
- #include
- int sem_wait(sem_t *sem);
- int sem_post(sem_t *sem);
- 成功:返回 0
- #include
- int sem_trywait(sem_t *sem);
- 成功:返回 0
- #include
- int sem_destory(sem_t *sem);
- 成功:返回 0
- #define _GNU_SOURCE
- #include
- #include
- #include
- #include
- #include
-
- sem_t sem1,sem2,sem3;//申请的三个信号量变量
-
- void *fun1(void *arg)
- {
- sem_wait(&sem1);//因sem1本身有资源,所以不被阻塞 获取后sem1-1 下次会会阻塞
- printf("%s:Pthread Come!\n",__FUNCTION__);
- sem_post(&sem2);// 使得sem2获取到资源
- pthread_exit(NULL);
- }
-
- void *fun2(void *arg)
- {
- sem_wait(&sem2);//因sem2在初始化时无资源会被阻塞,直至14行代码执行 不被阻塞 sem2-1 下次会阻塞
- printf("%s:Pthread Come!\n",__FUNCTION__);
- sem_post(&sem3);// 使得sem3获取到资源
- pthread_exit(NULL);
- }
-
- void *fun3(void *arg)
- {
- sem_wait(&sem3);//因sem3在初始化时无资源会被阻塞,直至22行代码执行 不被阻塞 sem3-1 下次会阻塞
- printf("%s:Pthread Come!\n",__FUNCTION__);
- sem_post(&sem1);// 使得sem1获取到资源
- pthread_exit(NULL);
- }
-
- int main()
- {
- int ret;
- pthread_t tid1,tid2,tid3;
- ret = sem_init(&sem1,0,1); //初始化信号量1 并且赋予其资源
- if(ret < 0){
- perror("sem_init");
- return -1;
- }
- ret = sem_init(&sem2,0,0); //初始化信号量2 让其阻塞
- if(ret < 0){
- perror("sem_init");
- return -1;
- }
- ret = sem_init(&sem3,0,0); //初始化信号3 让其阻塞
- if(ret < 0){
- perror("sem_init");
- return -1;
- }
- ret = pthread_create(&tid1,NULL,fun1,NULL);//创建线程1
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- ret = pthread_create(&tid2,NULL,fun2,NULL);//创建线程2
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- ret = pthread_create(&tid3,NULL,fun3,NULL);//创建线程3
- if(ret != 0){
- perror("pthread_create");
- return -1;
- }
- /*回收线程资源*/
- pthread_join(tid1,NULL);
- pthread_join(tid2,NULL);
- pthread_join(tid3,NULL);
-
- /*销毁信号量*/
- sem_destroy(&sem1);
- sem_destroy(&sem2);
- sem_destroy(&sem3);
-
- return 0;
- }

函数原型如下:
- #include
- // 初始化条件变量
- pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
- int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);//cond_at
- tr 通常为 NULL
- // 销毁条件变量
- int pthread_cond_destroy(pthread_cond_t *cond);
- 这些函数成功时都返回 0
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
- pthread_mutex_lock(&g_tMutex);
- // 如果条件不满足则,会 unlock g_tMutex
- // 条件满足后被唤醒,会 lock g_tMutex
- pthread_cond_wait(&g_tConVar, &g_tMutex);
- /* 操作临界资源 */
- pthread_mutex_unlock(&g_tMutex);
int pthread_cond_signal(pthread_cond_t *cond);
pthread_cond_signal(&g_tConVar);
- #include
- #include
- #include
- #include
- #include
-
- static char g_buf[1000];
- static pthread_mutex_t g_tMutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_cond_t g_tConVar = PTHREAD_COND_INITIALIZER;
-
- static void *my_thread_func (void *data)
- {
- while (1)
- {
- //sleep(1);
- /* 等待通知 */
- //while (g_hasData == 0);
- pthread_mutex_lock(&g_tMutex);
- pthread_cond_wait(&g_tConVar, &g_tMutex);
-
- /* 打印 */
- printf("recv: %s\n", g_buf);
- pthread_mutex_unlock(&g_tMutex);
- }
-
- return NULL;
- }
-
-
- int main(int argc, char **argv)
- {
- pthread_t tid;
- int ret;
- char buf[1000];
-
- /* 1. 创建"接收线程" */
- ret = pthread_create(&tid, NULL, my_thread_func, NULL);
- if (ret)
- {
- printf("pthread_create err!\n");
- return -1;
- }
-
-
- /* 2. 主线程读取标准输入, 发给"接收线程" */
- while (1)
- {
- fgets(buf, 1000, stdin);
- pthread_mutex_lock(&g_tMutex);
- memcpy(g_buf, buf, 1000);
- pthread_cond_signal(&g_tConVar); /* 通知接收线程 */
- pthread_mutex_unlock(&g_tMutex);
- }
- return 0;
- }
-


