您的位置:首页 > 文旅 > 旅游 > 深圳建筑设计平台网站_代理小企业网站建设_网络推广方案模板_上海seo公司哪家好

深圳建筑设计平台网站_代理小企业网站建设_网络推广方案模板_上海seo公司哪家好

2024/10/10 16:18:32 来源:https://blog.csdn.net/2303_79502195/article/details/142679576  浏览:    关键词:深圳建筑设计平台网站_代理小企业网站建设_网络推广方案模板_上海seo公司哪家好
深圳建筑设计平台网站_代理小企业网站建设_网络推广方案模板_上海seo公司哪家好

目录

前言

Linux线程概念

解决方法

注意事项⚠️

解决问题🔥

总结


前言

        我们上节提出了两个死循环不能同时运行,导致我们无法控制贪吃蛇的运动方向,本节我们便来解决这个问题。

Linux线程概念

        线程是一个进程内部的控制序列,更准确的定义是:线程是一个进程内部的控制序列。 一切进程都至少有一个执行线程。 线程在进程内部运行本质是在进程的地址空间内运行。 Linux中,在CPU眼中看到的PCB都比传统的进程更加轻量化。 透过进程的虚拟地址空间可以看到进程的大部分资源,将进程的资源合理分配给每个执行流,就形成了线程执行流。

         对于我们上节代码中:

int main()
{int key;initNcurse();initSnake();gamePic();while(1){moveSnake();gamePic();refresh();usleep(100000);}while (1){key = getch();switch (key){case 0402:printw("DOWN\n");break;case 0403:printw("UP\n");break;case 0404:printw("LEFT\n");break;case 0405:printw("RIGHT\n");break;}}getch();//防止程序退出endwin();return 0;
}

程序永远都不会执行下面那个循环里面的内容。(因为程序卡死在下面这个代码中)

while(1)
    {
        moveSnake();
        gamePic();
        refresh();
        usleep(100000);
    } 

因为这个是while(1)死循环。 

解决方法

        那么我们有什么方法可以解决这个问题,此时我们就要引入Linux线程这个概念了,

Linux线程简单理解如图:

我们给予了一个Linux的多线程程序参考使用:

#include <stdio.h>
#include <pthread.h>
void* thread( void *arg )
{printf( "This is a thread and arg = %d.\n", *(int*)arg);*(int*)arg = 0;return arg;
}
int main( int argc, char *argv[] )
{pthread_t th;int ret;int arg = 10;int *thread_ret = NULL;ret = pthread_create( &th, NULL, thread, &arg );if( ret != 0 ){printf( "Create thread error!\n");return -1;}printf( "This is the main process.\n" );pthread_join( th, (void**)&thread_ret );printf( "thread_ret = %d.\n", *thread_ret );return 0;
}

我们将上面的代码保存,取名为test1.c

我们打开终端准备编译运行这个文件:

上述内容演示是在macOS  Sonoma14.4.1版本中,

直接输入“gcc test1.c”也可以直接运行。

但是在其他Linux环境中,可能要加入以下指令:

gcc test1.c -o thread -lpthread 

上面的图片可以看出来,我这个系统不管那个指令都编译出了正确的可执行文件。 

 现在我们只需要模仿创造线程就可以解决这个问题。

注意事项⚠️

我们要包含创造线程的头文件“#include <pthread.h>

解决问题🔥

        通过多线程解决问题之前,我们先来封装两个函数:
 

void refreshJieMian()
{while(1){moveSnake();gamePic();refresh();usleep(100000);}
}

refreshJieMian()封装效果用来不停地刷新界面。 

void changeDir()
{int key;while (1){key = getch();switch (key){case 0402:printw("DOWN\n");break;case 0403:printw("UP\n");break;case 0404:printw("LEFT\n");break;case 0405:printw("RIGHT\n");break;}}
}

 changeDir()函数用来检测用户的按键输入。

 

    pthread_t t1;pthread_t t2;pthread_create( &t1, NULL, refreshJieMian, NULL);pthread_create( &t2, NULL, changeDir, NULL);

我们将key设置全局变量,用于检测多线程是否生效。

#include <curses.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>struct Snake
{int hang;int lie;struct Snake * next;
};struct Snake * head = NULL;
struct Snake * tail = NULL;int key;void initNcurse()
{initscr();keypad(stdscr,1);
}int hasSnakeNode(int i,int j)
{struct Snake * p;p = head;while(p != NULL){if(p->hang == i && p->lie == j){return 1;}p = p -> next;}return 0;    
}void gamePic()
{int hang;int lie;move(0,0);for(hang = 0;hang < 20;hang ++){if(hang == 0){for(lie = 0;lie < 20;lie ++){printw("--");}printw("\n");}if(hang >= 0 && hang <= 19){for(lie = 0;lie <= 20;lie ++){if(lie == 0 || lie == 20) printw("|");else if(hasSnakeNode(hang,lie)) printw("[]");else printw("  ");}printw("\n");}if(hang == 19){for(lie = 0;lie < 20;lie ++){printw("--");}printw("\n");printw("by beiweiqiuAC,%d\n",key);}}}void addNode()
{struct Snake * new = (struct Snake *)malloc(sizeof(struct Snake));new->hang = head->hang;new->lie = tail->lie+1;new->next = NULL;tail->next = new;tail = new;
}void initSnake(){struct Snake * p;while(head != NULL){p = head;head = head -> next;free(p);}head = (struct Snake *)malloc(sizeof(struct Snake));head->hang = 1;head->lie = 1;head->next = NULL;tail = head;addNode();addNode();addNode();addNode();
}void deleNode()
{// struct Snake * p;// p = head;head = head ->next;// free(p);
}void moveSnake()
{addNode();deleNode();if(tail ->hang == 0 || tail->lie == 0 || tail->hang == 20 || tail ->lie == 20){initSnake();}
}void* refreshJieMian()
{while(1){moveSnake();gamePic();refresh();usleep(100000);}
}void* changeDir()
{while (1){key = getch();switch (key){case 0402:printw("DOWN\n");break;case 0403:printw("UP\n");break;case 0404:printw("LEFT\n");break;case 0405:printw("RIGHT\n");break;}}
}int main()
{pthread_t t1;pthread_t t2;initNcurse();initSnake();gamePic();pthread_create( &t1, NULL,refreshJieMian, NULL);pthread_create( &t2, NULL, changeDir, NULL);while(1);getch();//防止程序退出endwin();return 0;
}

运行效果如下图所示:

我们每按下上下左右键程序都会给出反馈,并且小蛇也在一起运动,代表多线程成功创建。 

总结

         我们本节主要使用了Linux多线程来解决了两个死循环的问题,这也是多线程的初步使用和认识。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com