Linux的线程和进程

1. 查看源代码

1. 线程与进程

进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。

ubuntu安装pthread库

sudo apt-get install -y glibc-doc manpages-posix-dev

查看pthrea手册

 man pthreads
No manual entry for pthreads

安装manpages

$ sudo apt-get install manpages-posix manpages-posix-dev

Linux的线程和进程_第1张图片

2. 编译各个程序并在Ubuntu运行;理解并解释运行状态和结果

1. 多线程

(1)线程的创建与终止

#include
#include
#include
#define NUM_THREADS 5 
void *PrintHello(void *threadid){
 long tid;
 tid=(long)threadid;
 printf("Hello World!It's me,thread#%Ild!\n",tid);
 pthread_exit(NULL);
}
int main (int argc ,char *argv[])
{
 pthread_t threads[NUM_THREADS];int rc;
 long a;
 for(a=0;a<NUM_THREADS;a++){
  printf("In main:creating thread %Ild\n",a);
  rc=pthread_create(&threads[a],NULL,PrintHello,(void*)a);
  if(rc){
   printf("ERROR;return code from pthread_create()is%d\n",rc);
   exit(-1);
 }
}
printf("In main:exit!\n");
pthread_exit(NULL);
return 0;
}


编译并执行

gcc -o ptread pthread.c -lpthread
./ptread

Linux的线程和进程_第2张图片
由于线程的竞争每次输出结果的次序都不一样

(2)进程的连接与分离

#include 
#include 
#include 
#include 
#define NUM_THREADS 4

void *thread_func(void *index) { /* 线程函数 */
	int i;
	long tid;
	double result=0.0;
	tid = (long)index;
	printf("Thread %ld starting...\n",tid);

	for (i=0; i<1000000; i++) {
		result = result + sin(i) * tan(i); /* 进行数学运算 */
	}
	printf("Thread %ld done. Result = %e\n",tid, result);
	pthread_exit((void*) index); /* 带计算结果退出 */
}


int main (int argc, char *argv[]) {
	pthread_t tid_array[NUM_THREADS];
	int err;
	long index;
	void *status;

	for(index=0; index<NUM_THREADS; index++) {
		printf("Main: creating tid_array %ld\n", index);
		err = pthread_create(
			&tid_array[index], 
			NULL, 
			thread_func, 
			(void *)index
		); /* 创建线程 */
		if (err) {
			printf("ERROR; return code from pthread_create() is %d\n", err);
			exit(-1);
		}
	}

	for(index=0; index<NUM_THREADS; index++) {
		err = pthread_join(
			tid_array[index], 
			&status
		); /*等待线程终止,并获取返回值*/
		if (err) {
			printf("ERROR; return code from pthread_join() is %d\n", err);
			exit(-1);
		}
		printf("Main: completed join with tid_array %ld having a status of %ld\n",index,(long)status);
	}

	printf("Main: program completed. Exiting.\n");
	pthread_exit(NULL);
}



编译并运行

gcc -o b.out b.c -lpthread -lm
./b-2.out

Linux的线程和进程_第3张图片

(3)线程互斥量/互斥锁

#include
#include
#include
#include
#include

pthread_t tid[2];
pthread_mutex_t lock;

void* thread_func(void *arg)
{
	int id = (long)arg;
	int i = 0;

	pthread_mutex_lock(&lock); 			/* 使用互斥量保护临界区 ================== begin ================== */
	printf("Job %d started\n", id);
	for (i = 0; i < 5; i++)
	{
		printf("Job %d printing\n", id);
		usleep(10);
	}
	printf("Job %d finished\n", id);
	pthread_mutex_unlock(&lock);		/* 使用互斥量保护临界区 ================== end ================== */
	return NULL;
}

int main(void)
{
	long i = 0;
	int err;

	if (pthread_mutex_init(&lock, NULL) != 0) { 					/* (动态) 初始化  互斥量, 因为定义时候没有初始化 */
		printf("\n Mutex init failed\n");
		return 1;
	}

	while(i < 2) {
		err = pthread_create(&(tid[i]), NULL, &thread_func, (void*)i);
		if (err != 0)
		printf("Can't create thread :[%s]", strerror(err));
		i++;
	}

	pthread_join(tid[0], NULL);
	pthread_join(tid[1], NULL);
	pthread_mutex_destroy(&lock);									/* 用完销毁 */

	return 0;
}

编译并运行

gcc -o c.out c.c -lpthread -lm
./c.out

Linux的线程和进程_第4张图片

(4)条件变量使用

#include
#include
#include
#include
#include

pthread_t tid_array[3];
int sum = 0;
pthread_mutex_t sum_lock = PTHREAD_MUTEX_INITIALIZER;   /* 互斥量 (静态初始化)*/
pthread_cond_t condition_sum_ready = PTHREAD_COND_INITIALIZER; 						/* 条件量 (静态初始化) */

void * worker_thread_func(void *arg) {
	int i;
	long id = (long) arg;
	for (i = 0; i < 60; i++) {
		pthread_mutex_lock(&sum_lock);                 /* 使用互斥量保护临界变量 */
		printf("t%ld: read sum value before = %d\n", id + 1, sum);
		sum++;
		printf("t%ld: read sum value after  = %d\n", id + 1, sum);
		pthread_mutex_unlock(&sum_lock);               /* 结束互斥量保护临界变量 */
		if (sum >= 100)
			pthread_cond_signal(&condition_sum_ready); 								 /* 通过条件量 发送条件通知 -> 唤醒等待线程 */
	}
	return NULL;
}

void * waiting_thread_func(void *arg) {
	long id = (long) arg;
	pthread_mutex_lock(&sum_lock);
	while (sum < 100) 																/* 不满足条件将一直等待 */
		pthread_cond_wait(&condition_sum_ready, &sum_lock);                         /* 通过条件量 等待条件通知 -> 唤醒等待线程 */
	sum = 0;
	printf("waiting_thread_func: clear sum value [我是等待线程,已被唤醒。 ]\n");
	printf("t%ld: read sum value = %d\n", id + 1, sum);
	pthread_mutex_unlock(&sum_lock);
	return NULL;
}

int main(void) {
	int err;
	long i;
	for (i = 0; i < 2; i++) {
		err = pthread_create(&(tid_array[i]), NULL, &worker_thread_func, (void *) i);         /* 创建线程 1 线程 2 */
		if (err != 0) {
			printf("Can't create thread :[%s]", strerror(err));
		}
	}
	
	err = pthread_create(&(tid_array[2]), NULL, &waiting_thread_func, (void *) i);            /* 创建线程 3 */
	if (err != 0)
		printf("Can't create thread :[%s]", strerror(err));
	for (i = 0; i < 3; i++)
		pthread_join(tid_array[i], NULL);
	
	return 0;
}

编译并运行

gcc -o d.out d.c -lpthread -lm
./d.out

Linux的线程和进程_第5张图片

(5)进程获取测试环境变量代码

#include 
int main(int argc, char * argv[], char *env[])
    int i = 0;
    while (env[i])
    puts(env[i++]);
    return 0;

Linux的线程和进程_第6张图片

(6)创建进程程序代码

#include 
#include 
    pid_t fork(void);

编译执行

gcc -o fork.out fork.c
./fork.out

Linux的线程和进程_第7张图片

QEMU的下载

参考:https://www.csdn.net/tags/OtTaYgwsODIwOTAtYmxvZwO0O0OO0O0O.html

sudo apt-get install qemu-user-static

下载成功后,进入ubuntu-18.04_imx6ul_qemu_system目录,执行install_sdl.sh,如下所示

git  clone  https://e.coding.net/weidongshan/ubuntu-18.04_imx6ul_qemu_system.git

安装SDL
下载成功后,进入ubuntu-18.04_imx6ul_qemu_system目录,执行install_sdl.sh如下所示:

$ cd /home/ningye/Desktop/ubuntu-18.04_imx6ul_qemu_system/
$ ls
imx6ull-system-image  qemu-imx6ull-gui_test.sh  source
install_sdl.sh        qemu-imx6ull-nogui.sh     ubuntu-18.04_sdl-package
qemu                  README.md
qemu-imx6ull-gui.sh   rootfs_test
$ install_sdl.sh

运行QEMU

必须在Ubunut的桌面环境下启动终端,执行./qemu-imx6ull-gui.sh如下所示:

$ cd /home/ningye/Desktop/ubuntu-18.04_imx6ul_qemu_system/
$ ls
imx6ull-system-image  qemu-imx6ull-gui_test.sh  source
install_sdl.sh        qemu-imx6ull-nogui.sh     ubuntu-18.04_sdl-package
qemu                  README.md
qemu-imx6ull-gui.sh   rootfs_test
$ ./qemu-imx6ull-gui.sh

Linux的线程和进程_第8张图片

下载编译内核

参考:http://wiki.100ask.org/Qemu
安装 lzop 工具

$ sudo apt-get install lzop

下载源码

$ git clone https://e.coding.net/codebug8/repo.git
$ mkdir -p 100ask_imx6ull-qemu && cd 100ask_imx6ull-qemu
$ ../repo/repo init -u https://e.coding.net/weidongshan/manifests.git -b linux-sdk -m  imx6ull/100ask-imx6ull_qemu_release_v1.0.xml --no-repo-verify

下载成功后,可以得到如下内容

$ cd 100ask_imx6ull-qemu/
$ ls 
buildroot2019.02  linux-4.9.88  qemu  ToolChain

设置工具链

$ export ARCH=arm
$ export CROSS_COMPILE=arm-linux-gnueabihf-
$ export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin

配置、编译内核
安装交叉编译器(这一步很重要,否则无法编译)

$ sudo apt install gcc-arm-linux-gnueabihf        // 安装编译器。

执行如下命令:

$ cd linux-4.9.88
$ make mrproper
$ make 100ask_imx6ull_qemu_defconfig
$ make zImage     //这一步需要等待一段时间(10mins)

在QEMU中使用新的zImage
把编译出来的zImage复制到QEMU目录ubuntu-18.04_imx6ul_qemu_system/imx6ull-system-image即可:

$ cd ~/ubuntu-18.04_imx6ul_qemu_system/

替换LCD驱动程序
QEMU所用的内核里已经带有LCD驱动程序了,要测试我们编写的驱动程序,需要做2件事
把lcd_drv.c放到内核目录linux-4.9.88/drivers/video/fbdev

修改linux-4.9.88/drivers/video/fbdev/Makefile如下:

#obj-y += 100ask_qemu_fb.o
obj-y += lcd_drv.o

测试

Linux的线程和进程_第9张图片

参考
https://gitee.com/niuhouyun/pthread#https://gitee.com/linktarget=https%3A%2F%2Fwww.csdn.net%2Ftags%2FOtTaYgwsODIwOTAtYmxvZwO0O0OO0O0O.html

https://suliudrose.gitee.io/2022/04/11/qian-ru-shi-linux-xian-cheng-yu-jin-cheng/

你可能感兴趣的:(ubuntu,linux)