由于线程的东西讲解笔记多,我就不细说了,直接上代码吧
线程的编程要注意线程与线程之间不能混乱,我知道的有两种方式,加锁和信号量处理都可以。代码的注解写的比较详细,我就不多说了。以下代码提供参考,希望跟大家一起学习。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
/*使用条件变量可以以原子方式阻塞线程,
*直到某个特定条件为真为止。
*条件变量始终与互斥锁一起使用。
*对条件的测试是在互斥锁(互斥)的保护下进行的。
*在使用条件变量对其进行初始化
*/
/*条件变量初始化函数*/
//int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
/*销毁一个条件变量*/
int pthread_cond_destroy(pthread_cond_t *cond);
/*
*使用互斥锁(互斥)可以使线程按顺序执行。
*通常,互斥锁通过确保一次只有一个线程执行代码的临界段
*来同步多个线程。
*互斥锁还可以保护单线程代码。
*使用互斥锁,对其进行初始化操作
*/
/*加锁保护*/
int pthread_mutex_lock(pthread_mutex_t * mptr);
/*解锁释放*/
int pthread_mutex_unlock(pthread_mutex_t * mptr);
/*在用互斥量之前对其进行初始化*/
//int pthread_mutex_init(pthread_mutex_t *restrict muter,const pthread_mutexattr_t *restrict attr);
/*不在使用互斥量,就要销毁互斥量*/
int pthread_mutex_destroy(pthread_mutex_t *mutex);
/*创建线程函数*/
int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func) (void *), void *arg);
/*用于等待某个线程的退出*/
int pthread_join (pthread_t tid, void ** status);
/*用于返回当前的ip地址*/
pthread_t pthread_self (void);
/*用于指定线程变为分离的状态,如果线程变为分离的状态
线程释放的资源将会全部的释放,如果不是,那么线程就要保留线程的id
*/
int pthread_detach (pthread_t tid);
/*线程退出的函数*/
void pthread_exit (void *status);
void *thread2(void *str);
void *thread2(void *str);
/*
1)有一int型全局变量g_Flag初始值为0;
2)在主线称中起动线程1,打印“this is thread1”,并将g_Flag设置为1
3)在主线称中启动线程2,打印“this is thread2”,并将g_Flag设置为2
*/
int g_Flag = 0;
int g_i = 0;
int g_j = 0;
/*初始化线程id*/
pthread_t tid1;
pthread_t tid2;
/*初始化条件变量*/
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
/*使用默认参数初始化互斥量*/
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
/*延时函数*/
/*线程1的函数*/
void* thread1(void* arg)
{
/*
*初始化互斥量
1.使用默认参数
2.使用pthread_mutex_init()函数进行初始化
*/
/*加锁,防止对同一变量同时进行操作*/
pthread_mutex_lock(&lock);
printf("enter thread1\n");
if(g_Flag == 2)
{
/*条件为真,唤醒其他调用次条件的线程*/
pthread_cond_signal(&cond);
}
/*调用pthread_self获取线程id*/
printf("this is thread1, g_Flag: %d, thread id is %u\n",g_Flag, (unsigned int)pthread_self());
g_Flag = 1;
printf("this is thread1, g_Flag: %d, thread id is %u\n",g_Flag, (unsigned int)pthread_self());
/*退出本线程*/
printf("leave thread1\n");
/*解锁释放保护行为*/
pthread_mutex_unlock(&lock);
/*在线程2退出之后退出,如果线程不退出,进入挂起的状态*/
pthread_join(*(pthread_t*)arg, NULL);
//pthread_join (tid2, NULL);
/*退出本线程*/
printf("leave thread1\n");
pthread_exit(0);
}
/*线程2的函数*/
void* thread2(void *str)
{
/*
*初始化互斥量
1.使用默认参数
2.使用pthread_mutex_init()函数进行初始化
*/
/*加锁,防止对同一变量同时进行操作*/
pthread_mutex_lock(&lock);
printf("enter thread2\n");
printf("this is thread2, g_Flag: %d, thread id is %u\n",g_Flag, (unsigned int)pthread_self());
if(g_Flag == 1)
{
pthread_cond_signal(&cond);
}
g_Flag = 2;
printf("this is thread2, g_Flag: %d, thread id is %u\n",g_Flag, (unsigned int)pthread_self());
/*退出本线程*/
printf("leave thread2\n");
/*解锁释放保护行为*/
pthread_mutex_unlock(&lock);
pthread_exit(0);
}
/*调用完线程函数,要用析构函数释放内存*/
int main()
{
printf("enter main\n");
int err = 0;
/*struct timespec now;
struct timespec outtime;
gettimeofday(&now, NULL);
outtime.tv_sec = now.tv_sec + 5;
outtime.tv_usec = now.tv_usec * 1000;*/
/*创造线程2,打印this thread2,将g+Flag设置位为2*/
err = pthread_create(&tid2, NULL, thread2, NULL);
if(err)
{
printf("thread2 fail!\n");
return 0;
}
/*创造线程1,打印this thread1,将g+Flag设置位为1*/
err = pthread_create(&tid1, NULL, thread1, &tid2);
if(err)
{
printf("thread1 fail!\n");
return 0;
}
/*条件cond成立唤醒主线程
*默认情况下面,阻塞的线程会一直等待,知道某个条件变量为真
*/
pthread_cond_wait(&cond,&lock);
/*如果想设置最大的阻塞时间可以调用:pthread_cond_timedwait*/
//pthread_cond_timedwait (&cond,&lock,&outtime);
//while(1){;}
printf("leave main\n");
/*销毁互斥量*/
pthread_mutex_destroy(&lock);
/*销毁条件变量*/
pthread_cond_destroy(&cond);
/*退出主进程*/
exit (0);
return 0;
}