Linux学习之多线程编程(多线程的练习)

言之者无罪,闻之者足以戒。 ——《诗序》

1、创造一个线程,主线程打印奇数,新线程打印偶数,交替执行

下面来看程序:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
int flag=1;
//主线程打印奇数,新线程打印偶数,交替执行
void *thread_fun(void *arg)
{
        while(1)
        {
                //设置一个标志位,flag为0的时候新线程打印
                if(flag==0)
                {
                        flag=1;
                        (int)arg++;
                        printf("new thread print num=%d\n",(int)arg*2);
                }
                //新线程执行完之后进入睡眠,主线程执行(实现交替执行)
                sleep(1);
        }
}

int main()
{   
        int err,num=0;
        pthread_t tid;
        //创建新的线程
        err = pthread_create(&tid,NULL,thread_fun,(void *)num);
        if(err != 0)
        {
                printf("create new thread failure\n");
                return -1;
        }

        while(num < 20)
        {
                //设置一个标志位,flag为1的时候主线程打印
                if(flag==1)
                {
                        flag=0;
                        printf("main thread print num=%d\n",num*2+1);
                        num++;
                }
                //主线程执行完之后,进入休眠状态,新线程开始执行
                sleep(1);
        }
        return 0;
}

程序比较简单就不写设计思路了,我已经把一些必要的注释写上去了,以供参考。

2、创建10个线程,如果线程的参数和随机数相同,那么线程就采用exit方式退出

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>

//创建10个线程,如果线程的参数和随机数相同,那么就exit方式退出
int num;

void *thread_fun(void *arg)
{
        printf("I am %d thread\n",(int *)arg);
        //判断是否相等,如果相等就直接exit方式退出
        if(num == (int *)arg)
        {
                printf("the new thread %d exit\n",(int *)arg);
                exit(0);
        }
        //如果不相等就睡眠,让其他的线程运行
        sleep(2);
         
        pthread_exit((void *)0);
}   
int main()
{   
        pthread_t tid;
        int err;
        int i=10;
        //产生随机种子
        srand((unsigned int)time(NULL));
        //产生一个10以内的随机数
        num = rand()%11;

        while(i--)
        {
                //创建新的线程
                err = pthread_create(&tid,NULL,thread_fun,(void *)i);
                if(err != 0)
                {
                        printf("create new thread failure\n");
                        return -1;
                }

        }
        sleep(1);

        return 0;
}

3、一个线程被连接成功后,另一个线程就不能再连接该线程了

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
int err;
pthread_t tid1,tid2;

void *thread_fun1(void *arg)
{
        sleep(1);//进入睡眠状态,让线程2先执行
        printf("I am thread 1\n");
        pthread_exit((void *)0);
}
void *thread_fun2(void *arg)
{
        printf("I am thread 2\n"); 
        //连接线程1
        err = pthread_join(tid1,NULL);
        if(err != 0)
        {
                printf("new thread2 join thread 1 failure\n");
        }
        else 
        {
                printf("new thread2 join thread 1 success\n");
        }
        pthread_exit((void *)0);
}
int main()
{
        //创建新的线程1
        err = pthread_create(&tid1,NULL,thread_fun1,NULL);
        if(err != 0)
        {
                printf("create new thread1 failure\n");
                return 0;
        }
        //创建新的线程2
        err = pthread_create(&tid2,NULL,thread_fun2,NULL);
        if(err != 0)
        {
                printf("create new thread1 failure\n");
                return 0;
        }
        //连接线程1
        err = pthread_join(tid1,NULL);
        if(err != 0)
        {
                printf("main thread join thread 1 failure\n");
        }
        else
        {
                printf("main thread join thread 1 success\n");
        }
        return 0;
}

4、一个新线程可以自己取消自己

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
int err;
pthread_t tid;

void *thread_fun1(void *arg)
{
        printf("I am new thread\n");
        printf("I am to cancel myself\n");
        //设置取消类型为延时取消
        pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
        //设置取消状态为可以取消
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
        //取消自己
        err = pthread_cancel(pthread_self());
        if(err != 0) 
        {
                printf("cancel myself failure\n"); 
        }
        printf("cancel myself success\n");
        pthread_exit((void *)0);
}
int main()
{
        //创建新的线程1
        err = pthread_create(&tid,NULL,thread_fun1,NULL);
        if(err != 0)
        {
                printf("create new thread1 failure\n");
                return 0;
        }
        err = pthread_join(tid,NULL);
        if(err != 0)
        {
                printf("main thread join thread 1 failure\n");
        }
        else
        {
                printf("main thread join thread 1 success\n");
        }
        return 0;
}

5、使用多线程对一个队列进行增加和减少,增加操作是一个线程,删除操作是一个线程

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
pthread_mutex_t mutex;
pthread_once_t once = PTHREAD_ONCE_INIT;

struct queue{
	int len;
	int write_pos;
	int read_pos;
	int data[50];
};

//互斥量初始化函数
void mutex_init()
{
	int err;
	err = pthread_mutex_init(&mutex, NULL);
	if(err)
	{
		printf("mutex init failed\n");
		return;
	}
}

//队列初始化
struct queue *queue_init()
{
	struct queue *que;
	//申请内存
	que = (struct queue *)malloc(sizeof(struct queue));
	if(que ==NULL)
	{
		printf("malloc failed\n");
		return;
	}

	//初始化
	que->len = 0;
	que->write_pos = 0;
	que->read_pos = 0;

	return que;
}

void queue_destroy(struct queue *que)
{
	//销毁互斥量和que
	pthread_mutex_destroy(&mutex);
	free(que);
}

void *queue_add(void *arg)
{
	//对互斥量进行一次性初始化
	pthread_once(&once, mutex_init);
	struct queue *que = (struct queue *)arg;
	int buf=0;
	while(buf<50)
	{
		pthread_mutex_lock(&mutex);
		que->data[que->write_pos] = buf;
		que->write_pos ++;
		que->len ++;
		buf++;
		printf("write data %d to queue\n", que->data[que->write_pos -1]);

		pthread_mutex_unlock(&mutex);
		sleep(1);
	}
}

void *queue_del(void *arg)
{
	//	对互斥量进行一次性初始化
	pthread_once(&once, mutex_init);
	struct queue *que = (struct queue *)arg;
	int buf=0;
	while(1)
	{
		sleep(2);
		pthread_mutex_lock(&mutex);
		buf = que->data[que->read_pos];
		que->read_pos ++;
		if(que->len -- == 0)
		{
			printf("queue is empty\n");
			return;
		}
		buf++;
		printf("read data %d from queue\n", que->data[que->read_pos -1]);
		pthread_mutex_unlock(&mutex);
	}
}

int main()
{
	pthread_t tid1, tid2;
	int err;
	struct queue *que;

	//队列初始化
	que = queue_init();

	err = pthread_create(&tid1, NULL, queue_add, (void *)que);
	if(err)
	{
		printf("create add thread failed\n");
		queue_destroy(que);
		return;
	}

	err = pthread_create(&tid2, NULL, queue_del, (void *)que);
	if(err)
	{
		printf("create del thread failed\n");
		queue_destroy(que);
		return;
	}

	//等待增加和删除操作完成
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);

	//销毁
	queue_destroy(que);
}

猜你喜欢

转载自blog.csdn.net/weixin_42994525/article/details/83305322