Compare commits

..

14 Commits

Author SHA1 Message Date
flykhan 3b818d11bd sql 作业 7 2023-08-24 23:05:08 +08:00
flykhan e11f684219 sql 作业 1-6 2023-08-24 21:54:42 +08:00
flykhan b520c1de82 基本 sql 查询(指定列,条件查询,排序和分页查询) 2023-08-24 18:21:13 +08:00
flykhan db9e1dd070 基本 sql 练习 2023-08-24 17:18:04 +08:00
flykhan 8b63cc049a 多任务互斥与同步(互斥锁, 读写锁, 条件变量, 信号量, 命名信号量): 作业 2023-08-23 10:17:33 +08:00
flykhan 8e8af08fcf 多任务互斥与同步(互斥锁, 读写锁, 条件变量, 信号量, 命名信号量): 作业1,2,3,4,5,6 2023-08-23 00:55:06 +08:00
flykhan ffc2656985 多任务互斥与同步(互斥锁, 读写锁, 条件变量, 信号量, 命名信号量): 作业1,2,3,4,5 2023-08-23 00:24:34 +08:00
flykhan 721846a61d 多任务互斥与同步(互斥锁, 读写锁, 条件变量, 信号量, 命名信号量): 作业1,2,3,4修订 2023-08-22 23:49:28 +08:00
flykhan 663a501a63 多任务互斥与同步(互斥锁, 读写锁, 条件变量, 信号量, 命名信号量): 作业3 2023-08-22 23:34:57 +08:00
flykhan 0df47fc15c 多任务互斥与同步(互斥锁, 读写锁, 条件变量, 信号量, 命名信号量): 作业1,2 2023-08-22 21:47:54 +08:00
flykhan 7d8e55d275 多任务互斥与同步(互斥锁, 读写锁, 条件变量, 信号量, 命名信号量) 2023-08-22 20:46:40 +08:00
flykhan d1bc1e2410 线程作业 2023-08-21 22:01:14 +08:00
flykhan 8df60e2dc6 线程 2023-08-21 19:45:29 +08:00
flykhan 49d2f0cabb 消息队列,共享内存 2023-08-18 16:47:04 +08:00
96 changed files with 4026 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
// 消费者
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <unistd.h>
typedef struct data
{
char data[32];
int flag;
} Data;
int main()
{
printf("consumer\n");
key_t key = ftok("/", 15);
if (key == -1)
{
perror("ftok");
return 1;
}
int shmid = shmget(key, sizeof(Data), IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
return 1;
}
Data *data_buf = (Data *)shmat(shmid, NULL, 0);
if (data_buf == (Data *)-1)
{
perror("shmat");
return 1;
}
while (1)
{
while (data_buf->flag == 0)
;
sleep(1);
printf("read data: %s\n", data_buf->data);
data_buf->flag = 0;
}
return 0;
}
+25
View File
@@ -0,0 +1,25 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
// ftok()函数用于获取消息队列的键值
int main()
{
// 获取消息队列的键值,返回值是一个整数,表示消息队列(IPC)的键值
key_t key = ftok("/", 26);
printf("key = %d\n", key);
// ftok()函数的第一个参数是路径,第二个参数是索引值
// 索引值是一个整数,范围是0~255,用于区分不同的消息队列
// 超过255的索引值会被截断,例如256会被截断为0,257会被截断为1,相当于循环使用
key_t key2 = ftok("/", 26);
printf("key = %d\n", key2);
int mask = 0xff; // 0b11111111 低8位掩码
printf("mask = %d\n", mask);
// 低8位掩码与key进行与运算,得到低8位
printf("key & mask = %d\n", key & mask); // 用于获取低8位
printf("key2 & mask = %d\n", key2 & mask); // 用于获取低8位
return 0;
}
+31
View File
@@ -0,0 +1,31 @@
#include <stdio.h>
#include <sys/types.h> // 系统数据类型定义
#include <sys/ipc.h> // IPC相关头文件
#include <sys/msg.h> // 消息队列相关头文件
// msgget 函数用于创建消息队列,参数1是键值,参数2是权限
int main()
{
key_t key = ftok("/home/flykhan/", 200); // 获取消息队列的键值
printf("key = %d\n", key);
if (key == -1)
{
perror("ftok");
return 1;
}
// msgget 函数用于创建消息队列,参数1是键值,参数2是权限
// 返回值是消息队列的标识符,类似于文件描述符
// IPC_CREAT 表示如果消息队列不存在则创建,如果存在则打开
// 0644 表示权限,类似于文件权限,表示所有者可读写,其他人只读
int msgqid = msgget(key, IPC_CREAT | 0666); // 创建消息队列
if (msgqid == -1)
{
perror("msgget");
return 1;
}
// msgqid 只要不是 -1 就表示创建成功
printf("msgqid = %d\n", msgqid); // 打印消息队列标识符
return 0;
}
+102
View File
@@ -0,0 +1,102 @@
#include <stdio.h>
#include <sys/types.h> // 系统数据类型定义
#include <sys/ipc.h> // IPC相关头文件
#include <sys/msg.h> // 消息队列相关头文件
#include <string.h> // 字符串操作
#include <stdlib.h> // atol 函数
#include <time.h> // 时间函数
#include <unistd.h> // 头文件含义:unix standard,即unix标准的意思
// 消息结构体
typedef struct msg_
{
long mType; // 消息类型,必须是 long ,必须在第一个位置
char content[100]; // 消息内容,需要小于消息队列的限制值(8192)
char title[32]; // 消息标题
} MSG;
// msgget 函数用于创建消息队列,参数1是键值,参数2是权限
int main(int argc, char *argv[])
{
key_t key = ftok("/", 200); // 获取消息队列的键值
int msgqid = msgget(key, IPC_CREAT | 0666); // 创建消息队列
if (msgqid == -1)
{
perror("msgget");
return 1;
}
// 查看 msgqid 消息队列的信息
struct msqid_ds msginfo; // 消息队列信息结构体
int ret = msgctl(msgqid, IPC_STAT, &msginfo); // 获取消息队列信息
if (ret == -1)
{
perror("msgctl");
return 1;
}
time_t st = msginfo.msg_stime; // 最后发送消息的时间
time_t rt = msginfo.msg_rtime; // 最后接收消息的时间
time_t ct = msginfo.msg_ctime; // 最后变更消息的时间
struct tm *stm = localtime(&st); // 转换为北京时间
struct tm *rtm = localtime(&rt); // 转换为北京时间
struct tm *ctm = gmtime(&ct); // 转换为北京时间
// // 手动转换为北京时间
// st += 8 * 60 * 60;
// rt += 8 * 60 * 60;
// ct += 8 * 60 * 60;
// // 把时间戳转换为字符串
// char stime[32] = "";
// char rtime[32] = "";
// char ctime[32] = "";
// ctime_r(&st, stime);
// ctime_r(&rt, rtime);
// ctime_r(&ct, ctime);
// // 打印时间
// printf("最后发送消息的时间: %s", stime);
// printf("最后接收消息的时间: %s", rtime);
// printf("最后变更消息的时间: %s", ctime);
// printf("最后变更消息的时间: %s", ctime);
// + 1900 是因为 struct tm 结构体中的 tm_year 字段表示的是从1900年开始的年数的偏移量。
// +1 是因为 struct tm 结构体中的 tm_mon 字段表示的是月份的偏移量,范围是0-11,其中0表示一月,11表示十二月
printf("最后发送消息的时间: %d-%d-%d %d:%d:%d\n", stm->tm_year + 1900, stm->tm_mon + 1, stm->tm_mday, stm->tm_hour, stm->tm_min, stm->tm_sec);
printf("最后接收消息的时间: %d-%d-%d %d:%d:%d\n", rtm->tm_year + 1900, rtm->tm_mon + 1, rtm->tm_mday, rtm->tm_hour, rtm->tm_min, rtm->tm_sec);
printf("最后变更消息的时间: %d-%d-%d %d:%d:%d\n", ctm->tm_year + 1900, ctm->tm_mon + 1, ctm->tm_mday, ctm->tm_hour, ctm->tm_min, ctm->tm_sec);
// 打印消息队列的信息
printf("\n消息队列的信息:\n");
printf("消息队列的标识符: %d\n", msginfo.msg_perm.__key);
printf("消息队列的权限: %04o\n", msginfo.msg_perm.mode); // %04o 是八进制输出,占4位,不足4位前面补0
// 修改消息队列的权限
// msginfo.msg_perm.mode = 0644; // 修改权限
msginfo.msg_perm.mode |= 0111; // 修改权限,增加可执行权限
ret = msgctl(msgqid, IPC_SET, &msginfo);
if (ret == -1)
{
perror("msgctl");
return 1;
}
printf("修改消息队列的权限为: %04o\n", msginfo.msg_perm.mode); // %04o 是八进制输出,占4位,不足4位前面补0
// execlp("ipcs", "ipcs", "-q", NULL); // 打印消息队列
// 减少权限
msginfo.msg_perm.mode &= ~0101; // 修改权限,减少可执行权限
ret = msgctl(msgqid, IPC_SET, &msginfo);
if (ret == -1)
{
perror("msgctl");
return 1;
}
printf("修改消息队列的权限为: %04o\n", msginfo.msg_perm.mode); // %04o 是八进制输出,占4位,不足4位前面补0
execlp("ipcs", "ipcs", "-q", NULL); // 打印消息队列
return 0;
}
+29
View File
@@ -0,0 +1,29 @@
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
// 测试 msgctl ,用于删除消息队列
int main()
{
key_t key = ftok("/", 65); // 使用ftok函数生成一个唯一的键值
int msqid = msgget(key, 0666 | IPC_CREAT); // 创建或获取消息队列
if (msqid == -1)
{
perror("msgget");
exit(1);
}
// 控制操作:删除消息队列
if (msgctl(msqid, IPC_RMID, NULL) == -1)
{
perror("msgctl");
exit(1);
}
printf("Message queue removed successfully.\n");
return 0;
}
+47
View File
@@ -0,0 +1,47 @@
// 生产者
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <unistd.h>
typedef struct data
{
char data[32];
int flag;
} Data;
int main()
{
printf("producer\n");
key_t key = ftok("/", 15);
if (key == -1)
{
perror("ftok");
return 1;
}
int shmid = shmget(key, sizeof(Data), IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
return 1;
}
Data *data_buf = (Data *)shmat(shmid, NULL, 0);
if (data_buf == (Data *)-1)
{
perror("shmat");
return 1;
}
int num = 0;
while (1)
{
while (data_buf->flag == 1)
;
sprintf(data_buf->data, "hello, %d", num++);
data_buf->flag = 1;
printf("write data: %s\n", data_buf->data);
}
return 0;
}
+30
View File
@@ -0,0 +1,30 @@
// 共享内存
/*
是的,"shm"是共享内存(shared memory)的缩写,它通常用于表示共享内存相关的概念和操作。共享内存是一种进程间通信的机制,允许多个进程共享同一块内存区域,从而实现高效的数据交换和共享。
在Linux系统中,使用`shmget`函数创建或获取共享内存段(shared memory segment),进程可以通过该段共享内存进行通信。共享内存段是一个连续的内存区域,可以被多个进程映射到各自的地址空间中,从而实现共享数据的读写。
共享内存在进程间通信中具有高速和低开销的优势,因为进程可以直接读写共享内存,而无需进行复制或传输数据。但同时也需要注意正确地处理同步和互斥,以避免数据竞争和一致性问题。
因此,当你看到"shm"时,通常指的是共享内存,而"share mem"是它的完整表达形式。这两个术语可以互换使用,表示同一概念。
*/
#include <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
int main()
{
key_t key = ftok("/", 28);
// 获取共享内存的标识
int shmid = shmget(key, 32, IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
return 1;
}
printf("shmid=%d\n", shmid);
return 0;
}
+44
View File
@@ -0,0 +1,44 @@
// 共享内存
#include <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
// 共享内存写数据
int main()
{
key_t key = ftok("/", 28);
// 获取共享内存的标识
int shmid = shmget(key, 32, IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
return 1;
}
printf("shmid=%d\n", shmid);
// 获取共享内存的首地址
char *buf = shmat(shmid, NULL, 0); // NULL表示让系统自动分配共享内存的首地址
if (buf == (char *)-1)
{
perror("shmat");
return 1;
}
strcpy(buf, "hi, shared memory");
printf("write data ok\n");
/*
// 删除共享内存
int ret = shmctl(shmid, IPC_RMID, NULL); // 删除共享内存
if (ret == -1)
{
perror("shmctl");
return 1;
}
printf("shared memory deleted\n");
*/
return 0;
}
+42
View File
@@ -0,0 +1,42 @@
// 共享内存
#include <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
// 共享内存读数据
int main()
{
key_t key = ftok("/", 28);
// 获取共享内存的标识
int shmid = shmget(key, 32, IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
return 1;
}
printf("shmid=%d\n", shmid);
// 获取共享内存的首地址
char *buf = shmat(shmid, NULL, 0); // NULL表示让系统自动分配共享内存的首地址
if (buf == (char *)-1)
{
perror("shmat");
return 1;
}
printf("共享内存的数据:%s\n", buf);
/*
// 删除共享内存
int ret = shmctl(shmid, IPC_RMID, NULL); // 删除共享内存
if (ret == -1)
{
perror("shmctl");
return 1;
}
printf("shared memory deleted\n");
*/
return 0;
}
+42
View File
@@ -0,0 +1,42 @@
// 共享内存
#include <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
// 解除映射
int main()
{
key_t key = ftok("/", 28);
// 获取共享内存的标识
int shmid = shmget(key, 32, IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
return 1;
}
printf("shmid=%d\n", shmid);
// 获取共享内存的首地址
char *buf = shmat(shmid, NULL, 0); // NULL表示让系统自动分配共享内存的首地址
if (buf == (char *)-1)
{
perror("shmat");
return 1;
}
printf("共享内存的数据:%s\n", buf);
// 解除映射
int ret = shmdt(buf);
if (ret == -1)
{
perror("shmdt");
return 1;
}
printf("解除映射成功 ok\n");
return 0;
}
+47
View File
@@ -0,0 +1,47 @@
// 共享内存
#include <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
// 共享内存删除
int main()
{
key_t key = ftok("/", 28);
// 获取共享内存的标识
int shmid = shmget(key, 32, IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
return 1;
}
printf("shmid=%d\n", shmid);
// 获取共享内存的首地址
char *buf = shmat(shmid, NULL, 0); // NULL表示让系统自动分配共享内存的首地址
if (buf == (char *)-1)
{
perror("shmat");
return 1;
}
printf("共享内存的数据:%s\n", buf);
// 删除共享内存
// NULL 表示不关心共享内存的信息
// int ret = shmctl(shmid, IPC_RMID, NULL); // 删除共享内存
// 如果不写 NULL,应该写一个结构体,表示共享内存的信息
struct shmid_ds ds;
int ret = shmctl(shmid, IPC_RMID, &ds); // 删除共享内存
if (ret == -1)
{
perror("shmctl");
return 1;
}
printf("shared memory deleted\n");
return 0;
}
+109
View File
@@ -0,0 +1,109 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <unistd.h>
#include <sys/wait.h>
typedef struct data
{
int data;
int flag;
} Data;
int main()
{
key_t key = ftok("/", 28);
int shmid = shmget(key, sizeof(Data), IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
return 1;
}
if (fork() == 0) // 生产者进程
{
Data *data = shmat(shmid, NULL, 0);
if (data == (Data *)-1)
{
perror("shmat");
return 1;
}
data->flag = 0; // 初始化为 0
data->data = 0; // 初始化为 0
for (int i = 0; i < 100; i++)
{
// 等待消费者消费数据
while (data->flag == 1)
;
data->data++; // 生产数据
data->flag = 1;
printf("生产者生产数据:%d\n", data->data);
}
// 解除映射
if (shmdt(data) == -1)
{
perror("shmdt");
return 1;
}
_exit(0); // 子进程退出
}
if (fork() == 0) // 消费者进程
{
Data *data = shmat(shmid, NULL, 0);
if (data == (Data *)-1)
{
perror("shmat");
return 1;
}
data->flag = 0; // 初始化为 0
data->data = 0; // 初始化为 0
for (int i = 0; i < 100; i++)
{
// 等待生产者生产数据
while (data->flag == 0)
{
printf("等待生产者生产数据\n");
}
printf("消费者消费数据:%d\n", data->data);
// 消费到 100 时退出
if (data->data == 10)
break;
sleep(1);
data->flag = 0;
}
// 解除映射
if (shmdt(data) == -1)
{
perror("shmdt");
return 1;
}
_exit(0); // 子进程退出
}
while (1)
{
// WUNTRACED 不跟踪 ?
int pid = waitpid(0, NULL, WUNTRACED);
if (pid == -1)
{
break;
}
printf("%d 子进程结束\n", pid);
}
// 删除共享内存
if (shmctl(shmid, IPC_RMID, NULL) == -1)
{
perror("shmctl");
return 1;
}
return 0;
}
+28
View File
@@ -0,0 +1,28 @@
// 编写一个程序, 开启二个线程, 第一个线程向终端输出A, 第二个线程向终端输出B, 每个线程打印10遍。
#include <stdio.h>
#include <pthread.h>
void *printA(void *data)
{
for (int i = 0; i < 10; i++)
printf("A\n");
return NULL;
}
void *printB(void *data)
{
for (int i = 0; i < 10; i++)
printf("B\n");
return NULL;
}
int main()
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, printA, NULL);
pthread_create(&tid2, NULL, printB, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
+51
View File
@@ -0,0 +1,51 @@
// 编写一个程序, 创建一个线程, 该线程计算并打印斐波那契数列的前n项, n由用户输入
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h> // atoi
void *fibonacci(void *data)
{
int n = *((int *)data);
int a = 1, b = 1, c;
if (n >= 1)
{
c = a;
printf("%d\t", c);
}
if (n >= 2)
{
c = b;
printf("%d\t", c);
}
int temp = n - 2;
while (n > 2 && temp > 0)
{
c = a + b;
a = b;
b = c;
temp--;
printf("%d\t", c);
}
printf("\n");
return NULL;
}
int main(int argc, char const **argv)
{
if (argc != 2)
{
printf("用法: %s 数字\n", argv[0]);
return 0;
}
int input = atoi(argv[1]);
pthread_t tid;
pthread_create(&tid, NULL, fibonacci, (void *)&input);
pthread_join(tid, NULL);
return 0;
}
+37
View File
@@ -0,0 +1,37 @@
// 编写一个程序, 创建两个线程, 一个线程打印奇数, 另一个线程打印偶数, 要求交替打印1到100的数字。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *printOdd(void *data) // 打印奇数
{
for (int i = 1; i <= 100; i++)
{
usleep(100 * 1000); // 睡眠 0.1 秒
if (i % 2 == 1)
printf("奇数: %d\n", i);
}
return NULL;
}
void *printEven(void *data) // 打印偶数
{
for (int i = 1; i <= 100; i++)
{
usleep(100 * 1000); // 睡眠 0.1 秒
if (i % 2 == 0)
printf("偶数: %d\n", i);
}
return NULL;
}
int main(int argc, char const **argv)
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, printOdd, NULL);
pthread_create(&tid2, NULL, printEven, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
+50
View File
@@ -0,0 +1,50 @@
// 编写一个程序, 创建一个线程, 该线程从标准输入读取字符串, 然后将字符串逆序输出。
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
void *reverseOrder(void *data)
{
char *src_str = (char *)data;
int start = 0;
int end = strlen(src_str) - 1;
// 动态分配内存来存储反序的字符串,确保在主函数中使用 pthread_join 获取线程的返回值时,该字符串仍然有效
char *dst_str = (char *)malloc((strlen(src_str) + 1) * sizeof(char));
strcpy(dst_str, src_str);
while (start < end)
{
// 交换起始位置和末尾位置的字符
char tmp = dst_str[start];
dst_str[start] = dst_str[end];
dst_str[end] = tmp;
// 移动指针
start++;
end--;
}
pthread_exit(dst_str);
}
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("用法: %s 字符串\n", argv[0]);
return 0;
}
pthread_t tid;
pthread_create(&tid, NULL, reverseOrder, (void *)argv[1]);
char *dst_str;
pthread_join(tid, (void **)&dst_str);
printf("字符串反序后为:\n%s\n", dst_str);
// 释放动态分配的内存
free(dst_str);
return 0;
}
+74
View File
@@ -0,0 +1,74 @@
/*
, 线http://www.baidu.com, 由子线程完成网址的下载并写入到tmpN.html临时文件中, 并在子线程中打印输出结果.输入exit时, 退出程序.
execlp()`curl > tmp1.html`, N是第几次请求.
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
typedef struct url_info_s
{
char *url;
int N;
} URL_INFO;
void *download(void *data)
{
URL_INFO *info = (URL_INFO *)data;
char end_name[20];
sprintf(end_name, "tmp%d.html", info->N);
// execlp("curl", "curl", info->url, "-o", end_name, NULL);
// 注意:这里使用 "-o" 参数指定输出文件名
char command[200];
sprintf(command, "curl %s -o %s", info->url, end_name);
system(command);
sprintf(command, "cat %s", end_name);
system(command);
return NULL;
}
// void *view(void *data)
// {
// URL_INFO *info = (URL_INFO *)data;
// char end_name[20];
// sprintf(end_name, "tmp%d.html", info->N);
// execlp("cat", "cat", end_name, NULL);
// // 使用 execlp 调用 cat 命令打印输出结果
// return NULL;
// }
int main()
{
int n = 1; // 初始化 n 的值为 1
char buf[100];
while (1)
{
printf("请输入网址(输入exit退出):");
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = '\0';
if (strcmp(buf, "exit") == 0)
{
break;
}
URL_INFO urls;
urls.url = buf;
urls.N = n++;
pthread_t download_tid, view_tid;
pthread_create(&download_tid, NULL, download, &urls);
pthread_join(download_tid, NULL);
// pthread_create(&view_tid, NULL, view, &urls);
// pthread_join(view_tid, NULL);
}
printf("---over---\n");
return 0;
}
+83
View File
@@ -0,0 +1,83 @@
/*
线线
线
*/
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct array_s
{
int *arr; // 数组元素头指针
int start_pos; // 起始位置
int end_pos; // 结束位置
} ARRAY;
void *sort(void *data)
{
ARRAY *array = (ARRAY *)data;
for (int i = array->start_pos; i < array->end_pos; i++)
{
for (int j = array->start_pos; j < array->end_pos - i; j++)
{
if (array->arr[j] > array->arr[j + 1])
{
array->arr[j] ^= array->arr[j + 1];
array->arr[j + 1] ^= array->arr[j];
array->arr[j] ^= array->arr[j + 1];
}
}
}
return NULL;
}
int main()
{
int arr[9] = {1, 4, 2, 9, 0, 5, 6, 1, 8};
ARRAY array1 = {arr, 0, 2};
ARRAY array2 = {arr, 3, 5};
ARRAY array3 = {arr, 6, 8};
pthread_t t1, t2, t3;
pthread_create(&t1, NULL, sort, &array1);
pthread_create(&t2, NULL, sort, &array2);
pthread_create(&t3, NULL, sort, &array3);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
// 合并排序结果
int merged[9];
int i = 0;
for (int j = array1.start_pos; j <= array1.end_pos; j++)
{
merged[i++] = arr[j];
}
for (int j = array2.start_pos; j <= array2.end_pos; j++)
{
merged[i++] = arr[j];
}
for (int j = array3.start_pos; j <= array3.end_pos; j++)
{
merged[i++] = arr[j];
}
// 创建数组结构和新线程,将合并后的数组进行排序
ARRAY arr4 = {merged, 0, 8};
pthread_t t4;
pthread_create(&t4, NULL, sort, &arr4);
pthread_join(t4, NULL);
// 输出排序结果
printf("排序后的数组:");
for (int i = 0; i < 9; i++)
{
printf("%d ", merged[i]);
}
printf("\n");
return 0;
}
+79
View File
@@ -0,0 +1,79 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct array_s
{
int *arr; // 数组元素头指针
int start_pos; // 起始位置
int end_pos; // 结束位置
} ARRAY;
void *sort(void *data)
{
ARRAY *array = (ARRAY *)data;
for (int i = array->start_pos; i < array->end_pos; i++)
{
for (int j = array->start_pos; j < array->end_pos - i; j++)
{
if (array->arr[j] > array->arr[j + 1])
{
array->arr[j] ^= array->arr[j + 1];
array->arr[j + 1] ^= array->arr[j];
array->arr[j] ^= array->arr[j + 1];
}
}
}
return NULL;
}
int main()
{
int arr[9] = {1, 4, 2, 9, 0, 5, 6, 1, 8};
ARRAY array1 = {arr, 0, 2};
ARRAY array2 = {arr, 3, 5};
ARRAY array3 = {arr, 6, 8};
pthread_t t1, t2, t3;
pthread_create(&t1, NULL, sort, &array1);
pthread_create(&t2, NULL, sort, &array2);
pthread_create(&t3, NULL, sort, &array3);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
// 合并排序结果
int merged[9];
int i = 0;
for (int j = array1.start_pos; j <= array1.end_pos; j++)
{
merged[i++] = arr[j];
}
for (int j = array2.start_pos; j <= array2.end_pos; j++)
{
merged[i++] = arr[j];
}
for (int j = array3.start_pos; j <= array3.end_pos; j++)
{
merged[i++] = arr[j];
}
// 创建数组结构和新线程,将合并后的数组进行排序
ARRAY arr4 = {merged, 0, 8};
pthread_t t4;
pthread_create(&t4, NULL, sort, &arr4);
pthread_join(t4, NULL);
// 输出排序结果
printf("排序后的数组:");
for (int i = 0; i < 9; i++)
{
printf("%d ", merged[i]);
}
printf("\n");
return 0;
}
+2
View File
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
+7
View File
@@ -0,0 +1,7 @@
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.18.0 (Ubuntu)</center>
</body>
</html>
+10
View File
@@ -0,0 +1,10 @@
#include <stdio.h>
#include <pthread.h>
int main()
{
printf("当前线程号: %ld", pthread_self()); // 获取当前线程号
char test_char = getchar(); //阻塞程序的执行,等待用户输入一个字符后才会继续执行后面的代码
printf("获取到 %c\n", test_char);
return 0;
}
+38
View File
@@ -0,0 +1,38 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
// pthread_cleanup_push() 和 pthread_cleanup_pop()
// 线程清退示例
void *clear_task(void *args);
void *task1(void *data)
{
char *p = malloc(32);
pthread_cleanup_push(clear_task, (void *)p);
strcpy(p, "hello, disen!");
printf("%ld 线程在堆中分配的空间,内容为 %s\n", pthread_self(), p);
pthread_exit(p);
pthread_cleanup_pop(0);
}
void *clear_task(void *args)
{
char *msg = (char *)args;
printf("清退: %s\n", msg);
free(msg);
}
int main()
{
pthread_t tid;
char *q = NULL;
pthread_create(&tid, NULL, task1, NULL);
pthread_join(tid, (void **)&q);
printf("子线程退出结果: %s\n", q);
sleep(2);
return 0;
}
+68
View File
@@ -0,0 +1,68 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int global_data;
void clean(void *data) // 清理函数的耗时属于调用线程
{
printf("开始清理数据: %p\n", data);
global_data = *((int *)data);
free(data);
}
void *task(void *data)
{
int n = atoi((char *)data);
int *total = malloc(4);
pthread_cleanup_push(clean, total);
for (int i = 1; i <= n; i++)
{
*total += i;
usleep(200 * 1000);
}
pthread_cleanup_pop(1);
pthread_exit(NULL); // 加入清理函数后,但数据的退出无意义
}
typedef struct delay_cancel_info
{
pthread_t tid;
int delay;
} DELAY_INFO;
void *delay_cancel(void *data)
{
DELAY_INFO *info = (DELAY_INFO *)data;
sleep(info->delay);
printf("%ld 线程即将取消\n", info->tid);
pthread_cancel(info->tid);
}
int main(int argc, char const *argv[])
{
if (argc != 3)
{
printf("usage: %s number delay_time\n", argv[0]);
return 0;
}
pthread_t tid;
pthread_create(&tid, NULL, task, (void *)argv[1]);
DELAY_INFO info = {tid, atoi(argv[2])};
pthread_t tid2;
pthread_create(&tid2, NULL, delay_cancel, &info);
if (pthread_join(tid, NULL) == 0)
{
printf("%ld 子线程返回数据: %d\n", tid, global_data);
}
return 0;
}
/*
线线pthread_exit()线使
*/
+71
View File
@@ -0,0 +1,71 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void clean(void *data)
{
printf("---已清理---\n");
}
void *read_line(void *path)
{
pthread_cleanup_push(clean, NULL); // 注册清理函数
printf("按行读取 %s 数据\n", (char *)path);
sleep(2);
pthread_cleanup_pop(1); // 执行清理函数
}
int main(int argc, char const **argv)
{
if (argc != 3)
{
printf("usage: %s filepath1 filepath2", argv[0]);
return 0;
}
pthread_attr_t attr; // 线程属性
pthread_attr_init(&attr); // 初始化线程属性
// 设置线程分离 (通过属性修改)
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// 获取当前线程的栈的大小
size_t stackSize;
pthread_attr_getstacksize(&attr, &stackSize);
printf("线程默认的栈大小: %ld Mb\n", stackSize / 1024 / 1024);
stackSize /= 2;
pthread_attr_setstacksize(&attr, stackSize);
pthread_attr_getstacksize(&attr, &stackSize);
printf("修改后栈大小: %ld Mb\n", stackSize / 1024 / 1024);
// 获取当前线程的优先级
struct sched_param param;
pthread_attr_getschedparam(&attr, &param);
printf("默认线程的优先级: %d\n", param.__sched_priority);
pthread_t tid2;
pthread_create(&tid2, &attr, read_line, (void *)argv[2]);
pthread_t tid;
pthread_create(&tid, &attr, read_line, (void *)argv[1]); // 创建线程
param.__sched_priority = 10;
// 设置单个线程的优先级
pthread_setschedparam(tid, SCHED_FIFO, &param);
struct sched_param param2;
param2.__sched_priority = 12;
pthread_setschedparam(tid2, SCHED_FIFO, &param2);
int detachstate;
if (pthread_attr_getdetachstate(&attr, &detachstate) == 0) // 获取线程的分离状态
{
if (detachstate != PTHREAD_CREATE_DETACHED) // 如果线程不是分离状态
{
pthread_join(tid, NULL); // 等待线程结束
}
}
sleep(3);
pthread_attr_destroy(&attr); // 清理线程属性
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *task1(void *data)
{
printf("当前线程号(%ld): %s\n", pthread_self(), (char *)data);
// return NULL;
getchar();
}
int main()
{
pthread_t tid;
// 子线程成功之后,则会自动启动线程
int ret = pthread_create(&tid, NULL, task1, "hello");
printf("主线程(%ld)退出\n", pthread_self());
// sleep(3);
getchar();
return 0;
}
+37
View File
@@ -0,0 +1,37 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int n;
void *task1(void *data)
{
n += *((int *)data);
printf("子线程(%ld) n=%d\n", pthread_self(), n);
getchar();
}
int main()
{
pthread_t tid1, tid2;
// 子线程成功之后,则会自动启动线程
int m = 90;
int ret1 = pthread_create(&tid1, NULL, task1, &m);
if (ret1 != 0)
{
perror("pthread_create");
}
int m2 = 100;
int ret2 = pthread_create(&tid2, NULL, task1, &m2);
if (ret2 != 0)
{
perror("pthread_create");
}
printf("主线程(%ld)退出 n=%d\n", pthread_self(), n);
// sleep(3);
getchar();
return 0;
}
+40
View File
@@ -0,0 +1,40 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
void *thread_task(void *data)
{
int *arr = (int *)data;
int total = 0;
for (int i = arr[0]; i <= arr[1]; i++)
{
total += i;
}
int *result = malloc(sizeof(int));
*result = total;
return result;
}
int main()
{
pthread_t tid;
int arr[2] = {1, 100};
if (pthread_create(&tid, NULL, thread_task, arr) != 0)
{
perror("pthread_create");
return 1;
}
int *task_result;
// pthread_join函数等待子线程执行完毕,并将子线程的返回值存储在task_result指针中。注意,这里需要将task_result的类型为int*的指针的地址传递给pthread_join函数。
if (pthread_join(tid, (void **)&task_result) != 0)
{
perror("pthread_join");
return 1;
}
printf("线程返回的结果是: %d\n", *task_result);
free(task_result);
return 0;
}
+37
View File
@@ -0,0 +1,37 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
// pthread_detach 的使用
void *task1(void *data)
{
// 提供一个整数值,计算它的阶乘
int n = *((int *)data);
int *ret = (int *)malloc(sizeof(int));
*ret = 1;
while (n)
{
*ret *= n--;
}
printf("%d\n", *ret);
return NULL;
}
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("usage: ./%s 数字\n", argv[0]);
}
pthread_t tid;
int num = atoi(argv[1]);
pthread_create(&tid, NULL, task1, (void *)&num);
// detach 分离的线程不能再由此程序处理,归由系统管理
pthread_detach(tid);
sleep(0.5);
return 0;
}
+46
View File
@@ -0,0 +1,46 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
// pthread_detach 的使用
void *task1(void *data)
{
// 提供一个整数值,计算它的阶乘
int n = *((int *)data);
int *ret = (int *)malloc(sizeof(int));
*ret = 1;
while (n)
{
*ret *= n--;
}
pthread_exit(ret);
}
int main(int argc, char const *argv[])
{
if (argc != 3)
{
printf("usage: ./%s 数字1 数字2\n", argv[0]);
}
pthread_t tid, tid2;
int num = atoi(argv[1]);
pthread_create(&tid, NULL, task1, (void *)&num);
int *ret = (int *)malloc(sizeof(int));
pthread_join(tid, (void **)&ret);
int num2 = atoi(argv[2]);
pthread_create(&tid, NULL, task1, (void *)&num2);
int *ret2 = (int *)malloc(sizeof(int));
pthread_join(tid, (void **)&ret2);
printf("%d!*%d! = %d\n", num, num2, (*ret) * (*ret2));
sleep(0.5);
return 0;
}
+35
View File
@@ -0,0 +1,35 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
void *task1(void *data)
{
int n = *((int *)data);
int ret = 1;
while (n)
{
ret *= n--;
}
// pthread_exit(&ret);
return ret;
}
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("usage: ./%s 数字\n", argv[0]);
return 1;
}
pthread_t tid;
int num = atoi(argv[1]);
pthread_create(&tid, NULL, task1, (void *)&num);
int res;
pthread_join(tid, &res);
printf("%d\n", res);
return 0;
}
+50
View File
@@ -0,0 +1,50 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
// pthread_cancel 示例
int isCancel = 0;
void *show(void *data)
{
for (int i = 0; i < 100; i++)
{
printf("线程(%ld): i=%d\n", pthread_self(), i);
sleep(1);
if (isCancel)
{
printf("%ld 被取消\n", pthread_self());
break;
// pthread_cancel(pthread_self()); // 取消线程
}
}
pthread_exit(NULL);
}
void *watch_task(void *data)
{
while (1)
{
char n = getchar();
if (n == '1')
{
isCancel = 1;
break;
}
}
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t tid, tid2;
pthread_create(&tid, NULL, show, NULL);
pthread_create(&tid2, NULL, watch_task, NULL);
pthread_join(tid, NULL);
pthread_join(tid2, NULL);
return 0;
}
+44
View File
@@ -0,0 +1,44 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
// pthread_cancel 示例 2
void *show(void *data)
{
for (int i = 0; i < 100; i++)
{
printf("线程(%ld): i=%d\n", pthread_self(), i);
sleep(1);
}
pthread_exit(NULL);
}
void *watch_task(void *data)
{
pthread_t brother_th = *((pthread_t *)data);
while (1)
{
char n = getchar();
if (n == '1')
{
printf("取消兄弟 %ld 线程\n", brother_th);
pthread_cancel(brother_th); // 根据传入的兄弟线程号取消兄弟线程
break;
}
}
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t tid, tid2;
pthread_create(&tid, NULL, show, NULL);
pthread_create(&tid2, NULL, watch_task, &tid); // 将兄弟线程号传递过去
pthread_join(tid, NULL);
pthread_join(tid2, NULL);
return 0;
}
+49
View File
@@ -0,0 +1,49 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *task1(void *data)
{
for (int i = 0; i < 10; i++)
{
printf("%ld 子线程执行了 %d 次\n", pthread_self(), i + 1);
sleep(1);
}
return NULL;
}
void *task2(void *data)
{
for (int i = 0; i < 100; i++)
{
if (i % 2 == 0)
printf("%ld 子线程, 偶数 %d 次\n", pthread_self(), i);
sleep(1);
}
return NULL;
}
void *clear(void *args)
{
char *msg = (char *)args;
printf("清退: %s\n", msg);
}
int main()
{
pthread_t tid, tid2;
pthread_create(&tid, NULL, task1, NULL);
pthread_create(&tid2, NULL, task2, NULL);
pthread_cleanup_push(clear, "task1");
pthread_cleanup_push(clear, "task2");
pthread_join(tid2, NULL);
pthread_cleanup_pop(1);
pthread_join(tid, NULL);
pthread_cleanup_pop(1);
return 0;
}
+83
View File
@@ -0,0 +1,83 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 条件变量实例
// 互斥锁和条件变量的初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *producer_task(void *data)
{
int *n = (int *)data;
while (1)
{
pthread_mutex_lock(&mutex);
while (*n == 10) // 只要资源为 10 ,就等待
{
// 条件变量等待后,会自动释放 mutex 锁
pthread_cond_wait(&cond, &mutex);
}
(*n)++;
printf("生产线程(%ld)生产了 %d 个产品\n", pthread_self(), *n);
// 发出通知,让等待消费的线程恢复(条件满足)
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
// usleep(200 * 1000);
sleep(1);
}
pthread_exit(NULL);
}
void *consumer_task(void *data)
{
int *n = (int *)data;
while (1)
{
pthread_mutex_lock(&mutex);
while (*n == 0) // 只要资源为 0 ,就等待
{
// 条件变量等待后,会自动释放 mutex 锁
pthread_cond_wait(&cond, &mutex);
}
printf("消费者(%ld) 消费了 %d 产品\n", pthread_self(), *n);
(*n)--;
pthread_mutex_unlock(&mutex);
// usleep(200 * 1000);
sleep(1);
}
pthread_exit(NULL);
}
int main(int argc, char const *argv[])
{
int num = 3; // 3 个产品
pthread_t threads[10];
// 创建 2 个生产线程
for (int i = 0; i < 8; i++)
{
pthread_create(&threads[i], NULL, producer_task, &num);
}
// 创建 3 个消费者线程
for (int i = 8; i < 10; i++)
{
pthread_create(&threads[i], NULL, consumer_task, &num);
}
for (int i = 0; i < 10; i++)
{
pthread_join(threads[i], NULL);
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
BIN
View File
Binary file not shown.
+58
View File
@@ -0,0 +1,58 @@
// 编写一个程序, 创建两个线程, 一个线程负责打印奇数, 另一个线程负责打印偶数, 要求打印的结果为1、2、3、4、5、6..., 直到指定的最大值。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *printOdd(void *data) // 打印奇数
{
int *n = (int *)data;
for (int i = 1; i <= *n; i++)
{
usleep(100 * 1000); // 睡眠 0.1 秒
if (i % 2 == 1)
{
printf("%d", i);
if (i != *n) // 不是最后一个字符,则追加'、'
printf("");
else if (i == *n) // 到最后一个字符,则追加'\n'换行
printf("\n");
fflush(stdout);
}
}
return NULL;
}
void *printEven(void *data) // 打印偶数
{
int *n = (int *)data;
for (int i = 1; i <= *n; i++)
{
usleep(100 * 1000); // 睡眠 0.1 秒
if (i % 2 == 0)
{
printf("%d", i);
if (i != *n)
printf("");
else if (i == *n)
printf("\n");
fflush(stdout);
}
}
return NULL;
}
int main(int argc, char const **argv)
{
int *n;
printf("请输入最大值: ");
fflush(stdout);
scanf("%d", n);
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, printOdd, (void *)n);
pthread_create(&tid2, NULL, printEven, (void *)n);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
+85
View File
@@ -0,0 +1,85 @@
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex;
pthread_cond_t condition;
int max_number;
int current_number;
void *print_odd(void *arg)
{
while (1)
{
pthread_mutex_lock(&mutex);
while (current_number % 2 == 0)
{ // 等待偶数线程通知
pthread_cond_wait(&condition, &mutex);
}
if (current_number > max_number)
{ // 达到最大值时退出
pthread_mutex_unlock(&mutex);
break;
}
printf("%d", current_number);
if (current_number != max_number)
printf("");
else if (current_number == max_number)
printf("\n");
fflush(stdout);
current_number++;
pthread_cond_signal(&condition); // 通知偶数线程
pthread_mutex_unlock(&mutex);
}
return NULL;
}
void *print_even(void *arg)
{
while (1)
{
pthread_mutex_lock(&mutex);
while (current_number % 2 != 0)
{ // 等待奇数线程通知
pthread_cond_wait(&condition, &mutex);
}
if (current_number > max_number)
{ // 达到最大值时退出
pthread_mutex_unlock(&mutex);
break;
}
printf("%d", current_number);
if (current_number != max_number)
printf("");
else if (current_number == max_number)
printf("\n");
fflush(stdout);
current_number++;
pthread_cond_signal(&condition); // 通知奇数线程
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main()
{
printf("请输入指定的最大值: ");
scanf("%d", &max_number);
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&condition, NULL);
current_number = 1;
pthread_t odd_thread, even_thread;
pthread_create(&odd_thread, NULL, print_odd, NULL);
pthread_create(&even_thread, NULL, print_even, NULL);
pthread_join(odd_thread, NULL);
pthread_join(even_thread, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&condition);
return 0;
}
+69
View File
@@ -0,0 +1,69 @@
/*
, 线, 线, 线线, 线, 线
main函数中创建char , 线
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int buffer_empty = 1; // 缓冲区是否为空的标志,初始为空
void *w_thread(void *data)
{
char *str = (char *)data;
pthread_rwlock_wrlock(&rwlock); // 获取写入锁
while (!buffer_empty) // 当缓冲区非空时,释放锁,等待 1 毫秒再次尝试获取写入锁
{
pthread_rwlock_unlock(&rwlock); // 释放写入锁
usleep(1000); // 等待缓冲区为空
pthread_rwlock_wrlock(&rwlock); // 再次获取写入锁
}
printf("请输入内容:");
fflush(stdout); // 刷新输出缓冲
scanf("%s", str);
buffer_empty = 0; // 缓冲区非空
pthread_rwlock_unlock(&rwlock); // 释放写入锁
return NULL;
}
void *r_thread(void *data)
{
char *str = (char *)data;
pthread_rwlock_rdlock(&rwlock); // 获取读取锁
while (buffer_empty) // 当缓冲区为空时,释放锁,等待1毫秒缓冲区非空后(等待写缓冲区线程写入内容),再次获取锁,直到判断非空,在进行后续打印
{
pthread_rwlock_unlock(&rwlock); // 释放读取锁
usleep(1000); // 等待缓冲区非空
pthread_rwlock_rdlock(&rwlock); // 再次获取读取锁
}
printf("输入的内容为: %s\n", str);
buffer_empty = 1; // 缓冲区为空
pthread_rwlock_unlock(&rwlock); // 释放读取锁
return NULL;
}
int main(int argc, char const *argv[])
{
char str[100];
pthread_t t1, t2;
pthread_create(&t1, NULL, w_thread, (void *)str);
pthread_create(&t2, NULL, r_thread, (void *)str);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_rwlock_destroy(&rwlock); // 销毁读写锁
return 0;
}
+66
View File
@@ -0,0 +1,66 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int buffer_empty = 1; // 缓冲区是否为空的标志,初始为空
void *w_thread(void *data)
{
char *str = (char *)data;
pthread_mutex_lock(&mutex); // 获取互斥锁
while (!buffer_empty) // 当缓冲区非空时,等待条件变量被唤醒
{
pthread_cond_wait(&cond, &mutex);
}
printf("请输入内容:");
fflush(stdout); // 刷新输出缓冲
scanf("%s", str);
buffer_empty = 0; // 缓冲区非空
pthread_cond_signal(&cond); // 唤醒等待的读取线程
pthread_mutex_unlock(&mutex); // 释放互斥锁
return NULL;
}
void *r_thread(void *data)
{
char *str = (char *)data;
pthread_mutex_lock(&mutex); // 获取互斥锁
while (buffer_empty) // 当缓冲区为空时,等待条件变量被唤醒
{
pthread_cond_wait(&cond, &mutex);
}
printf("输入的内容为: %s\n", str);
buffer_empty = 1; // 缓冲区为空
pthread_cond_signal(&cond); // 唤醒等待的写入线程
pthread_mutex_unlock(&mutex); // 释放互斥锁
return NULL;
}
int main(int argc, char const *argv[])
{
char str[100];
pthread_t t1, t2;
pthread_create(&t1, NULL, w_thread, (void *)str);
pthread_create(&t2, NULL, r_thread, (void *)str);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_cond_destroy(&cond); // 销毁条件变量
pthread_mutex_destroy(&mutex); // 销毁互斥锁
return 0;
}
+42
View File
@@ -0,0 +1,42 @@
/*
, 线, 线线, 线,
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
sem_t sem;
int number = 0;
void *
addfun(void *data)
{
sem_wait(&sem);
number++;
printf("%ld 线程时, number = %d\n", pthread_self(), number);
sem_post(&sem);
}
int main(int argc, char const *argv[])
{
sem_init(&sem, 0, 1);
printf("开始的 number = %d\n", number);
pthread_t t[5];
for (int i = 0; i < 5; i++)
{
pthread_create(&t[i], NULL, addfun, NULL);
}
for (int i = 0; i < 5; i++)
{
pthread_join(t[i], NULL);
}
printf("现在的 number = %d\n", number);
sem_destroy(&sem); // 销毁信号量
return 0;
}
+95
View File
@@ -0,0 +1,95 @@
/*
, 线, 线线, 线线
*/
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct array_s
{
int *arr; // 数组元素头指针
int start_pos; // 起始位置
int end_pos; // 结束位置
pthread_mutex_t *mutex; // 互斥锁
} ARRAY;
void *sort(void *data)
{
ARRAY *array = (ARRAY *)data;
pthread_mutex_lock(array->mutex); // 线程加锁
printf("%ld 线程开始排序\n", pthread_self());
for (int i = array->start_pos; i < array->end_pos; i++)
{
for (int j = array->start_pos; j < array->end_pos - i; j++)
{
if (array->arr[j] > array->arr[j + 1])
{
array->arr[j] ^= array->arr[j + 1];
array->arr[j + 1] ^= array->arr[j];
array->arr[j] ^= array->arr[j + 1];
}
}
}
pthread_mutex_unlock(array->mutex); // 线程解锁
return NULL;
}
int main()
{
int arr[9] = {1, 4, 2, 9, 0, 5, 6, 1, 8};
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
ARRAY array1 = {arr, 0, 2, &mutex};
ARRAY array2 = {arr, 3, 5, &mutex};
ARRAY array3 = {arr, 6, 8, &mutex};
pthread_t t1, t2, t3;
pthread_create(&t1, NULL, sort, &array1);
pthread_create(&t2, NULL, sort, &array2);
pthread_create(&t3, NULL, sort, &array3);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
// 合并排序结果
int merged[9];
int i = 0;
for (int j = array1.start_pos; j <= array1.end_pos; j++)
{
merged[i++] = arr[j];
}
for (int j = array2.start_pos; j <= array2.end_pos; j++)
{
merged[i++] = arr[j];
}
for (int j = array3.start_pos; j <= array3.end_pos; j++)
{
merged[i++] = arr[j];
}
pthread_mutex_unlock(&mutex); // 解锁
// 创建数组结构和新线程,将合并后的数组进行排序
ARRAY arr4 = {merged, 0, 8, &mutex};
pthread_t t4;
pthread_create(&t4, NULL, sort, &arr4);
pthread_join(t4, NULL);
// 输出排序结果
printf("排序后的数组:");
for (int i = 0; i < 9; i++)
{
printf("%d ", merged[i]);
}
printf("\n");
pthread_mutex_destroy(&mutex); // 销毁互斥锁
return 0;
}
+87
View File
@@ -0,0 +1,87 @@
/*
, 线, 线, 线线, ,
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 互斥锁和条件变量初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_p = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_c = PTHREAD_COND_INITIALIZER;
int current = 0;
int max = 100;
int min = 0;
void *producer(void *data)
{
while (1)
{
pthread_mutex_lock(&mutex); // 生产者加锁
while (current == max)
{
pthread_cond_wait(&cond_p, &mutex);
}
current++;
printf("+++++++++++++++++++++生成者 %ld 完成生产, 仓库剩余 %d 个商品\n", pthread_self(), current);
pthread_cond_broadcast(&cond_c); // 发出通知,让等待消费的线程恢复(条件满足)
pthread_mutex_unlock(&mutex); // 生产者解锁
usleep(100 * 1000);
}
pthread_exit(NULL);
}
void *consumer(void *data)
{
while (1)
{
pthread_mutex_lock(&mutex); // 消费者加锁
while (current == min)
{
pthread_cond_wait(&cond_c, &mutex);
}
current--;
printf("----------------------消费者 %ld 完成消费, 仓库剩余 %d 个商品\n", pthread_self(), current);
pthread_cond_broadcast(&cond_p);
pthread_mutex_unlock(&mutex);
usleep(150 * 1000);
}
pthread_exit(NULL);
}
int main(int argc, char const *argv[])
{
// 生产者线程
const int num_producer = 10; // 生产者数量
pthread_t t_producer[num_producer];
for (int i = 0; i < num_producer; i++)
{
pthread_create(&t_producer[i], NULL, producer, NULL);
}
// 消费者线程
const int num_consumer = 10; // 消费者数量
pthread_t t_consumer[num_consumer];
for (int i = 0; i < num_consumer; i++)
{
pthread_create(&t_consumer[i], NULL, consumer, NULL);
}
// join
for (int i = 0; i < num_producer; i++)
{
pthread_join(t_producer[i], NULL);
}
for (int i = 0; i < num_consumer; i++)
{
pthread_join(t_consumer[i], NULL);
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond_c);
pthread_cond_destroy(&cond_p);
return 0;
}
+95
View File
@@ -0,0 +1,95 @@
/*
, 线, 线线, 线线
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
typedef struct node
{
char name[32];
struct node *next;
} Node;
Node *head; // 定义头节点
void *find(void *data)
{
int n = 0; // 标识待查询内容在链表中的索引号
char *name = (char *)data;
pthread_mutex_lock(&mutex);
// 查询
Node *p = head->next;
while (p != NULL)
{
if (strcmp(p->name, name) == 0)
{
printf("%s 在链表的索引为 %d\n", name, n);
pthread_mutex_unlock(&mutex);
return NULL;
}
n++;
p = p->next;
}
printf("%s 在链表中未找到\n", name);
pthread_mutex_unlock(&mutex);
return NULL;
}
// 添加节点
void add_node(Node *head, char *name)
{
Node *p = head;
while (p->next != NULL)
p = p->next;
Node *new_node = (Node *)malloc(sizeof(Node));
if (NULL == new_node)
{
perror("malloc error");
return;
}
memset(new_node, 0, sizeof(Node)); // 初始化新节点为默认值
strcpy(new_node->name, name);
p->next = new_node;
}
int main(int argc, char const *argv[])
{
head = (Node *)malloc(sizeof(Node));
if (NULL == head)
{
perror("malloc error");
return 1;
}
memset(head, 0, sizeof(Node));
add_node(head, "a");
add_node(head, "b");
add_node(head, "c");
add_node(head, "d");
// 待查询字符表,包含查询的字符顺序
char *alphabet[4] = {"a", "e", "d", "b"};
pthread_t t[4];
for (int i = 0; i < 4; i++)
{
pthread_create(&t[i], NULL, find, (void *)alphabet[i]);
}
for (int i = 0; i < 4; i++)
{
pthread_join(t[i], NULL);
}
pthread_mutex_destroy(&mutex);
return 0;
}
+58
View File
@@ -0,0 +1,58 @@
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <semaphore.h>
//设置办理业务的人数
int num = 5;
//创建信号量
sem_t sem;
//模拟办理业务的过程
void *get_service(void *arg)
{
int id = *((int *)arg);
//信号量成功“减 1”后才能继续执行
if (sem_wait(&sem) == 0)
{
printf("---customer%d 正在办理业务\n", id);
sleep(2);
printf("---customer%d 已办完业务\n", id);
//信号量“加 1”
sem_post(&sem);
}
return 0;
}
int main()
{
int flag, i, j;
//创建 5 个线程代表 5 个人
pthread_t customer[5];
//初始化信号量
sem_init(&sem, 0, 2);
for (i = 0; i < num; i++)
{
flag = pthread_create(&customer[i], NULL, get_service, &i);
if (flag != 0)
{
printf("线程创建失败!\n");
return 0;
}
else
{
printf("customer%d 来办理业务\n", i);
}
sleep(1);
}
for (j = 0; j < num; j++)
{
flag = pthread_join(customer[j], NULL);
if (flag != 0)
{
printf("tid=%d 等待失败!", customer[i]);
return 0;
}
}
sem_destroy(&sem);
return 0;
}
+58
View File
@@ -0,0 +1,58 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 定义两把锁
pthread_mutex_t mutex1, mutex2;
void *task1(void *data)
{
char *taskName = (char *)data;
pthread_mutex_lock(&mutex1);
printf("%s 获取锁 1 成功, 等待 1 秒后获取锁 2\n", taskName);
sleep(1);
pthread_mutex_lock(&mutex2);
printf("%s 获取锁 2 成功\n", taskName);
printf("%s\n", taskName);
// 释放锁
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
return NULL;
}
void *task2(void *data)
{
char *taskName = (char *)data;
pthread_mutex_lock(&mutex1);
printf("%s 获取锁 1 成功, 等待 1 秒后获取锁 2\n", taskName);
sleep(1);
pthread_mutex_lock(&mutex2);
printf("%s 获取锁 2 成功\n", taskName);
printf("%s\n", taskName);
// 释放锁
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
return NULL;
}
int main(int argc, char const *argv[])
{
// 动态初始化锁
pthread_mutex_init(&mutex1, NULL);
pthread_mutex_init(&mutex2, NULL);
// 创建线程
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, task1, "hello");
pthread_create(&tid2, NULL, task2, "world");
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
// 销毁锁
pthread_mutex_destroy(&mutex1);
pthread_mutex_destroy(&mutex2);
return 0;
}
+45
View File
@@ -0,0 +1,45 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
// 命名信号实例
void printer(char *msg)
{
while (*msg)
{
printf("%c", *msg++); // 打印字符
fflush(stdout); // 刷新控制台
sleep(1);
}
}
int main(int argc, char const *argv[])
{
// 命名信号
sem_t *sem = sem_open("mysem", O_CREAT | O_RDWR, 0644, 1);
int pid = fork();
if (pid == 0) // 子进程
{
sem_wait(sem);
printer("disen666");
sem_post(sem);
_exit(0);
}
else if (pid > 0) // 父进程
{
sem_wait(sem);
printer("jack888");
sem_post(sem);
wait(NULL); // 等待子进程退出
printf("\n---over---\n");
sem_close(sem); // 关闭信号量
sem_unlink("mysem"); // 删除信号量文件
}
return 0;
}
+48
View File
@@ -0,0 +1,48 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
// 命名信号实例
void printer(char *msg)
{
while (*msg)
{
printf("%c", *msg++); // 打印字符
fflush(stdout); // 刷新控制台
sleep(1);
}
}
int main(int argc, char const *argv[])
{
// 命名信号
sem_t *sem1 = sem_open("mysem1", O_CREAT | O_RDWR, 0644, 1);
sem_t *sem2 = sem_open("mysem2", O_CREAT | O_RDWR, 0644, 0);
int pid = fork();
if (pid == 0) // 子进程
{
sem_wait(sem1);
printer("disen666");
sem_post(sem2);
_exit(0);
}
else if (pid > 0) // 父进程
{
sem_wait(sem2);
printer("jack888");
sem_post(sem1);
wait(NULL); // 等待子进程退出
printf("\n---over---\n");
sem_close(sem1); // 关闭信号量
sem_close(sem2); // 关闭信号量
sem_unlink("mysem1"); // 删除信号量文件
sem_unlink("mysem2"); // 删除信号量文件
}
return 0;
}
+34
View File
@@ -0,0 +1,34 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
// 无血缘关系的进程的互斥
void printer(char *msg)
{
while (*msg)
{
printf("%c", *msg++);
fflush(stdout);
sleep(1);
}
}
int main(int argc, char const *argv[])
{
// 打开信号量文件
sem_t *sem = sem_open("mysem", O_CREAT | O_RDWR, 0666, 1);
sem_wait(sem);
#ifdef DISEN
printer("disen666\n");
#else
printer("jack888\n");
#endif
sem_post(sem);
sem_close(sem);
return 0;
}
+38
View File
@@ -0,0 +1,38 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
// 无血缘关系的进程的同步
void printer(char *msg)
{
while (*msg)
{
printf("%c", *msg++);
fflush(stdout);
sleep(1);
}
}
int main(int argc, char const *argv[])
{
// 打开信号量文件
sem_t *sem1 = sem_open("mysem1", O_CREAT | O_RDWR, 0666, 1);
sem_t *sem2 = sem_open("mysem2", O_CREAT | O_RDWR, 0666, 0);
#ifdef DISEN
sem_wait(sem2);
printer("disen666\n");
sem_post(sem1);
#else
sem_wait(sem1);
printer("jack888\n");
sem_post(sem2);
#endif
sem_close(sem1);
sem_close(sem2);
return 0;
}
+28
View File
@@ -0,0 +1,28 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *printer(void *data)
{
char *msg = (char *)data;
while (*msg)
{
printf("%c", *msg++);
fflush(stdout);
sleep(1);
}
return NULL;
}
int main(int argc, char const **argv)
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, printer, "disen666\0");
pthread_create(&tid2, NULL, printer, "lucy888\0");
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
printf("---over---\n");
return 0;
}
+42
View File
@@ -0,0 +1,42 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 静态初始化互斥锁
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// 动态初始化锁-定义锁
pthread_mutex_t mutex;
void *printer(void *data)
{
char *msg = (char *)data;
pthread_mutex_lock(&mutex); // 申请上锁,可能阻塞
while (*msg)
{
printf("%c", *msg++);
fflush(stdout);
usleep(200 * 1000);
}
pthread_mutex_unlock(&mutex); // 不解锁,就会发生死锁
return NULL;
}
int main(int argc, char const **argv)
{
// 动态初始化锁-初始化
pthread_mutex_init(&mutex, NULL);
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, printer, "disen666\n");
pthread_create(&tid2, NULL, printer, "lucy888\n");
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
printf("\n---over---\n");
// 销毁互斥锁
pthread_mutex_destroy(&mutex);
return 0;
}
+54
View File
@@ -0,0 +1,54 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 静态初始化互斥锁
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// 动态初始化锁-定义锁
pthread_mutex_t mutex;
void *printer(void *data)
{
char *msg = (char *)data;
int lock_acquired = 0; // 未获取到锁
while (!lock_acquired) // 未获取到锁的时候,循环尝试获取锁,并处理
{
// trylock 非阻塞锁
if (pthread_mutex_trylock(&mutex) == 0) // 如果拿到锁
{
lock_acquired = 1; // 该状态:已获取到锁
while (*msg) // 当前线程传入的字符串未读取完成时,循环读取
{
printf("%c", *msg++);
fflush(stdout);
usleep(200 * 1000);
}
pthread_mutex_unlock(&mutex); // 读完后,解锁当前进程
}
else
{
usleep(100); // 0.1 毫秒后继续尝试获取锁
}
}
return NULL;
}
int main(int argc, char const **argv)
{
// 动态初始化锁-初始化
pthread_mutex_init(&mutex, NULL);
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, printer, "disen666\n");
pthread_create(&tid2, NULL, printer, "lucy888\n");
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
printf("\n---over---\n");
// 销毁互斥锁
pthread_mutex_destroy(&mutex);
return 0;
}
+52
View File
@@ -0,0 +1,52 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 定义读写锁(需要 GNU99
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; // 静态初始化读写锁
void *read_task(void *data)
{
int *n = (int *)data;
while (1)
{
pthread_rwlock_rdlock(&rwlock); // 申请读锁 rdlock
printf("(%ld)线程读取 num: %d\n", pthread_self(), *n);
pthread_rwlock_unlock(&rwlock); // 解锁
usleep(500 * 1000);
}
return NULL;
}
void *write_task(void *data)
{
int *n = (int *)data;
while (1)
{
pthread_rwlock_wrlock(&rwlock); // 申请写锁 wrlock
(*n)++;
printf("(%ld) 线程写 num: %d\n", pthread_self(), *n);
pthread_rwlock_unlock(&rwlock); // 解锁
sleep(2);
}
return NULL;
}
int main(int argc, char const *argv[])
{
int num; // 公共资源
pthread_t t1, t2, t3;
pthread_create(&t1, NULL, read_task, &num);
pthread_create(&t2, NULL, read_task, &num);
pthread_create(&t3, NULL, write_task, &num);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_rwlock_destroy(&rwlock); // 销毁读写锁
return 0;
}
+97
View File
@@ -0,0 +1,97 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int money = 1000; // 存款余额
int exit_flag = 0; // 退出标志
void *task1(void *data)
{
while (1)
{
pthread_rwlock_wrlock(&rwlock); // 加写锁
// 查询余额
printf("存款任务-余额: %d\n", money);
usleep(200 * 1000);
// 从键盘读取存入的金额
printf("请输入存款金额 (输入 0 结束存款): ");
fflush(stdout);
int m;
scanf("%d", &m);
if (m == 0)
{
exit_flag = 1;
pthread_rwlock_unlock(&rwlock); // 解锁
break;
}
money += m;
// 修改余额并打印结果
printf("存款成功, 余额为 %d\n", money);
pthread_rwlock_unlock(&rwlock); // 解锁
}
pthread_exit(NULL);
}
void *task2(void *data)
{
while (1)
{
pthread_rwlock_wrlock(&rwlock); // 加写锁
// 查询余额
printf("取款任务-余额: %d\n", money);
usleep(200 * 1000);
// 从键盘读取取出的金额
printf("请输入取款金额 (输入 0 结束取款): ");
fflush(stdout);
int m;
scanf("%d", &m);
if (m == 0)
{
exit_flag = 1;
pthread_rwlock_unlock(&rwlock); // 解锁
break;
}
if (money >= m)
{
money -= m;
// 修改余额并打印结果
printf("取款成功, 余额为 %d\n", money);
}
else
{
printf("取款失败, 余额不足\n");
}
pthread_rwlock_unlock(&rwlock); // 解锁
}
pthread_exit(NULL);
}
int main(int argc, char const *argv[])
{
while (1)
{
pthread_t t1, t2;
pthread_create(&t1, NULL, task1, NULL);
pthread_create(&t2, NULL, task2, NULL);
while (1)
{
pthread_rwlock_rdlock(&rwlock);
if (exit_flag)
{
pthread_rwlock_unlock(&rwlock);
break;
}
pthread_rwlock_unlock(&rwlock);
}
pthread_join(t1, NULL);
pthread_join(t2, NULL);
}
pthread_rwlock_destroy(&rwlock);
return 0;
}
+48
View File
@@ -0,0 +1,48 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
// 信号量实例
sem_t sem; // 定义信号量
void *printer(void *data)
{
char *msg = (char *)data;
// P 操作
sem_wait(&sem); // 本案例中锁住了控制台
while (*msg)
{
printf("%c", *msg++);
fflush(stdout);
usleep(200 * 1000);
}
// V 操作
sem_post(&sem);
return NULL;
}
int main(int argc, char const **argv)
{
// 信号量初始化
sem_init(&sem, 0, 1);
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, printer, "disen666\n");
pthread_create(&tid2, NULL, printer, "lucy888\n");
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
printf("\n---over---\n");
// 销毁信号量
sem_destroy(&sem);
return 0;
}
+105
View File
@@ -0,0 +1,105 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <semaphore.h>
// 信号量实例 2 - 存取款
sem_t sem; // 定义信号量
int money = 1000; // 存款余额
int exit_flag = 0; // 退出标志
void *task1(void *data)
{
while (1)
{
sem_wait(&sem); // P 操作
// 查询余额
printf("存款任务-余额: %d\n", money);
usleep(200 * 1000);
// 从键盘读取存入的金额
printf("请输入存款金额 (输入 0 结束存款): ");
fflush(stdout);
int m;
scanf("%d", &m);
if (m == 0)
{
exit_flag = 1;
sem_post(&sem); // V 操作
break;
}
money += m;
// 修改余额并打印结果
printf("存款成功, 余额为 %d\n", money);
sem_post(&sem); // V 操作
}
pthread_exit(NULL);
}
void *task2(void *data)
{
while (1)
{
sem_wait(&sem); // P 操作
// 查询余额
printf("取款任务-余额: %d\n", money);
usleep(200 * 1000);
// 从键盘读取取出的金额
printf("请输入取款金额 (输入 0 结束取款): ");
fflush(stdout);
int m;
scanf("%d", &m);
if (m == 0)
{
exit_flag = 1;
sem_post(&sem); // V 操作
break;
}
if (money >= m)
{
money -= m;
// 修改余额并打印结果
printf("取款成功, 余额为 %d\n", money);
}
else
{
printf("取款失败, 余额不足\n");
}
sem_post(&sem); // V 操作
}
pthread_exit(NULL);
}
int main(int argc, char const *argv[])
{
// 初始化信号量
sem_init(&sem, 0, 1);
while (1)
{
pthread_t t1, t2;
pthread_create(&t1, NULL, task1, NULL);
pthread_create(&t2, NULL, task2, NULL);
while (1)
{
sem_wait(&sem); // P 操作
if (exit_flag)
{
sem_post(&sem); // V 操作
break;
}
sem_post(&sem); // V 操作
}
pthread_join(t1, NULL);
pthread_join(t2, NULL);
}
// 销毁信号量
sem_destroy(&sem);
return 0;
}
+88
View File
@@ -0,0 +1,88 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>
sem_t sem1, sem2; // 信号量
void *task1(void *data)
{
int *money = (int *)data;
// 存款任务
sem_wait(&sem1);
// 查询余额
printf("存款任务-余额: %d\n", *money);
sleep(1);
// 从键盘读取存入的金额
printf("请输入存款金额: ");
fflush(stdout);
int m;
scanf("%d", &m);
*money += m;
// 修改余额并打印结果
printf("存款成功, 余额为: %d\n", *money);
sem_post(&sem2);
pthread_exit(NULL);
}
void *task2(void *data)
{
int *money = (int *)data;
// 取款任务
sem_wait(&sem2);
// 查询余额
printf("取款任务-余额: %d\n", *money);
sleep(1);
// 从键盘读取取出的金额
printf("请输入取款金额: ");
fflush(stdout);
int m;
scanf("%d", &m);
if (*money >= m)
{
*money -= m;
// 修改余额并打印结果
printf("取款成功, 余额为: %d\n", *money);
}
else
{
printf("取款失败,余额不足\n");
}
sem_post(&sem1);
pthread_exit(NULL);
}
int main(int argc, char const *argv[])
{
// 初始化信号量
sem_init(&sem1, 0, 1); // 存款的信号量初始化
sem_init(&sem2, 0, 0); // 取款的信号量初始化
int money = 1000; // 存款
while (1)
{
printf("输入 exit 退出 , 输入其他内容开始存取款\n");
char input[100];
scanf("%s", input);
if (strncmp(input, "exit", 4) == 0)
{
break;
}
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, task1, &money);
pthread_create(&tid2, NULL, task2, &money);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
}
sem_destroy(&sem1);
sem_destroy(&sem2);
return 0;
}
+3
View File
@@ -0,0 +1,3 @@
use studb;
+4
View File
@@ -0,0 +1,4 @@
use studb;
-- 所有列的查询
select * from t_stu;
+6
View File
@@ -0,0 +1,6 @@
use studb;
-- 查询2022年入职的所有员工
select *
from t_emp
where hire_date between '2022-01-01' and '2022-12-31';
+7
View File
@@ -0,0 +1,7 @@
use studb;
-- 按学生的出生日期降序显示
select *
from t_stu
order by birthday desc;
+10
View File
@@ -0,0 +1,10 @@
use studb;
-- 显示年龄最大的前两位学生
-- 出去 NULL
select *
from t_stu
where birthday is not null
-- 年龄越大,出生日期越前
order by birthday asc
limit 0,2;
+12
View File
@@ -0,0 +1,12 @@
use studb;
-- 按1页显示2条数据的方式,显示学生表的第2页数据
/*
limit offset, size offset是0开始的, 0
offset = (page-1)*size, page是页号, size是每一页显示的大小
*/
select *
from t_stu
limit 2,2;
+4
View File
@@ -0,0 +1,4 @@
use studb;
-- 查询指定的列
select sid, name from t_stu;
+5
View File
@@ -0,0 +1,5 @@
use studb;
-- 查询到的内容按指定的标题显示
select sid '学号', name as '姓名'
from t_stu;
+4
View File
@@ -0,0 +1,4 @@
use studb;
select t_stu.sid,t_stu.sex
from t_stu;
+5
View File
@@ -0,0 +1,5 @@
use studb;
-- 使用表的别名查询
select a.*
from t_stu a;
+5
View File
@@ -0,0 +1,5 @@
use studb;
-- 查询字段是一个表达式
select sid, name, 100 as score
from t_stu;
+10
View File
@@ -0,0 +1,10 @@
use studb;
-- 从多个表中查询数据时,如果存在相同的字段时,字段名前必须加表名
select *
from t_stu t1, t_stu t2;
where t1.sid > 2 and t2.sid > 3;
/*
*/
+11
View File
@@ -0,0 +1,11 @@
use studb;
-- 从多个表中查询数据时,如果存在相同的字段时,字段名前必须加表名
select distinct t1.sid
from t_stu t1, t_stu t2;
where t1.sid > 2 and t2.sid > 3;
/*
7
*/
+6
View File
@@ -0,0 +1,6 @@
use studb;
-- 查询员工表中手机号第7位是8的员工
select *
from t_emp
where tel like '______8%';
+6
View File
@@ -0,0 +1,6 @@
use studb;
-- 查询disen和jack两位员工
select *
from t_emp
where name in ('disen', 'jack');
+171
View File
@@ -0,0 +1,171 @@
-- MySQL dump 10.13 Distrib 5.7.33, for Linux (x86_64)
--
-- Host: localhost Database: studb
-- ------------------------------------------------------
-- Server version 5.7.33-0ubuntu0.16.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `t_course`
--
DROP TABLE IF EXISTS `t_course`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_course` (
`cid` int(11) DEFAULT NULL,
`name` varchar(50) DEFAULT NULL COMMENT '课程名',
`tid` int(11) DEFAULT NULL COMMENT '教师编号'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_course`
--
LOCK TABLES `t_course` WRITE;
/*!40000 ALTER TABLE `t_course` DISABLE KEYS */;
/*!40000 ALTER TABLE `t_course` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_emp`
--
DROP TABLE IF EXISTS `t_emp`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_emp` (
`emp_id` int(11) DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
`tel` char(11) DEFAULT NULL,
`salary` decimal(10,2) DEFAULT NULL,
`hire_date` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_emp`
--
LOCK TABLES `t_emp` WRITE;
/*!40000 ALTER TABLE `t_emp` DISABLE KEYS */;
INSERT INTO `t_emp` VALUES (1,'jack','17189792205',13000.00,'2021-10-12'),(2,'lucy','17178982206',3200.00,'2022-11-15'),(3,'disen','17178979385',23000.00,'2022-10-12');
/*!40000 ALTER TABLE `t_emp` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_score`
--
DROP TABLE IF EXISTS `t_score`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_score` (
`sid` int(11) DEFAULT NULL,
`cid` int(11) DEFAULT NULL,
`score` decimal(5,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_score`
--
LOCK TABLES `t_score` WRITE;
/*!40000 ALTER TABLE `t_score` DISABLE KEYS */;
/*!40000 ALTER TABLE `t_score` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_stu`
--
DROP TABLE IF EXISTS `t_stu`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_stu` (
`sid` int(11) DEFAULT NULL,
`name` varchar(20) DEFAULT NULL,
`sex` varchar(2) DEFAULT NULL,
`birthday` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_stu`
--
LOCK TABLES `t_stu` WRITE;
/*!40000 ALTER TABLE `t_stu` DISABLE KEYS */;
INSERT INTO `t_stu` VALUES (1,'张三','','1990-12-28'),(2,'王龙','','1991-01-07'),(3,'刘冬冬','','1992-08-21'),(4,'刘红','','1998-02-15'),(5,'王玉玉','',NULL);
/*!40000 ALTER TABLE `t_stu` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_stu3`
--
DROP TABLE IF EXISTS `t_stu3`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_stu3` (
`sid` int(11) DEFAULT NULL,
`name` varchar(20) DEFAULT NULL,
`sex` varchar(2) DEFAULT NULL,
`birthday` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_stu3`
--
LOCK TABLES `t_stu3` WRITE;
/*!40000 ALTER TABLE `t_stu3` DISABLE KEYS */;
INSERT INTO `t_stu3` VALUES (1,'张三','','1990-12-28'),(3,'刘冬冬','','1992-08-21'),(5,'王玉玉','',NULL);
/*!40000 ALTER TABLE `t_stu3` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_tch`
--
DROP TABLE IF EXISTS `t_tch`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_tch` (
`tid` int(11) DEFAULT NULL,
`name` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_tch`
--
LOCK TABLES `t_tch` WRITE;
/*!40000 ALTER TABLE `t_tch` DISABLE KEYS */;
/*!40000 ALTER TABLE `t_tch` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2023-08-24 17:01:50
+6
View File
@@ -0,0 +1,6 @@
-- comment 表示字段的说明 (备份)
create table t_course(
cid int,
name varchar(50) comment '课程名',
tid int comment '教师编号'
);
+10
View File
@@ -0,0 +1,10 @@
use studb;
-- 员工表
create table t_emp(
emp_id int,
name varchar(50),
tel char(11),
salary decimal(10,2),
hire_date date
);
+5
View File
@@ -0,0 +1,5 @@
create table t_score(
sid int,
cid int,
score decimal(5,2)
);
+7
View File
@@ -0,0 +1,7 @@
-- sql comment
create table t_student(
sid int,
name varchar(20),
sex varchar(2),
birthday date
);
+4
View File
@@ -0,0 +1,4 @@
create table t_teacher(
tid integer,
name varchar(50)
);
+4
View File
@@ -0,0 +1,4 @@
use studb;
delete from t_emp where hire_date > '2022-12-31';
select * from t_emp;
+8
View File
@@ -0,0 +1,8 @@
-- 删除测试
use studb;
create table if not exists t_stu3
select * from t_stu;
delete from t_stu3
where sex='';
+109
View File
@@ -0,0 +1,109 @@
-- MySQL dump 10.13 Distrib 5.7.33, for Linux (x86_64)
--
-- Host: localhost Database: bookdb
-- ------------------------------------------------------
-- Server version 5.7.33-0ubuntu0.16.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `images`
--
DROP TABLE IF EXISTS `images`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `images` (
`img_id` int(11) NOT NULL,
`title` varchar(50) DEFAULT NULL,
`width` int(11) DEFAULT NULL,
`height` int(11) DEFAULT NULL,
PRIMARY KEY (`img_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `images`
--
LOCK TABLES `images` WRITE;
/*!40000 ALTER TABLE `images` DISABLE KEYS */;
INSERT INTO `images` VALUES (1,'Image Set 1',800,600),(2,'Image Set 2',1024,768),(3,'Image Set 3',1280,720),(4,'Image Set 4',800,600),(5,'Image Set 5',1024,768),(6,'Image Set 6',1280,720),(7,'Image Set 7',800,600),(8,'Image Set 8',1024,768),(9,'Image Set 9',1280,720),(10,'Image Set 10',800,600);
/*!40000 ALTER TABLE `images` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `login`
--
DROP TABLE IF EXISTS `login`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `login` (
`login_id` int(11) NOT NULL,
`name` varchar(50) DEFAULT NULL,
`auth_string` varchar(50) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`last_time` datetime DEFAULT NULL,
PRIMARY KEY (`login_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `login`
--
LOCK TABLES `login` WRITE;
/*!40000 ALTER TABLE `login` DISABLE KEYS */;
INSERT INTO `login` VALUES (1001,'张三','zspasswd','2021-08-29 12:30:23','2023-06-05 23:10:23'),(1002,'李四','lspasswd','2022-08-29 12:30:23','2023-07-05 21:10:23'),(1003,'王五','wwpasswd','2023-04-29 12:30:23','2023-06-14 23:23:23');
/*!40000 ALTER TABLE `login` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `profile_info`
--
DROP TABLE IF EXISTS `profile_info`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `profile_info` (
`login_id` int(11) NOT NULL,
`real_name` varchar(50) DEFAULT NULL,
`nick_name` varchar(50) DEFAULT NULL COMMENT '昵称',
`sex` char(1) DEFAULT '',
`head` text COMMENT '用户头像图片文件的路径',
`phone` varchar(11) DEFAULT NULL,
PRIMARY KEY (`login_id`),
CONSTRAINT `profile_info_ibfk_1` FOREIGN KEY (`login_id`) REFERENCES `login` (`login_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `profile_info`
--
LOCK TABLES `profile_info` WRITE;
/*!40000 ALTER TABLE `profile_info` DISABLE KEYS */;
INSERT INTO `profile_info` VALUES (1001,'张三','三三','','/path/to/head1.jpg','12345678901'),(1002,'李四','四四','','/path/to/head2.jpg','12345678902'),(1003,'王五','五五','','/path/to/head3.jpg','12345678903');
/*!40000 ALTER TABLE `profile_info` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2023-08-24 20:52:25
+29
View File
@@ -0,0 +1,29 @@
/*
bookdbbookdb数据库中创建login登录表 login(login_id , name , passwd create_time , last_time )
*/
-- 删除原有数据库
-- drop database if exists bookdb;
-- 创建数据库
CREATE DATABASE IF NOT EXISTS bookdb;
-- 进入bookdb数据库
USE bookdb;
-- 创建login表
CREATE TABLE IF NOT EXISTS
login(
-- 主键
login_id INT PRIMARY KEY,
name VARCHAR(50),
passwd VARCHAR(50),
create_time DATETIME,
last_time DATETIME
);
-- 显示数据库bookdb结构
SHOW TABLES;
-- 显示表结构
DESCRIBE login;
+33
View File
@@ -0,0 +1,33 @@
/*
bookdb库中创建 person
person(login_id real_name , nick_name , sex性别, head , phone )
1. login_id是引用login表的login_id
2. head是存储用户头像图片文件的路径
3. sex 使"default 默认值"
*/
-- 进入 bookdb 数据库
USE bookdb;
-- 创建 person 个人信息表
CREATE TABLE IF NOT EXISTS
person(
-- 主键
login_id INT,
real_name VARCHAR(50),
nick_name VARCHAR(50) COMMENT '昵称',
sex CHAR(1) DEFAULT '',
head TEXT COMMENT '用户头像图片文件的路径',
phone VARCHAR(11),
-- 外键约束
FOREIGN KEY (login_id) REFERENCES login(login_id)
);
-- 显示数据库 bookdb 结构
SHOW TABLES;
-- 显示 person 表结构
DESCRIBE person;
+39
View File
@@ -0,0 +1,39 @@
/*
loginperson表中插入3条记录
*/
-- 进入bookdb数据库
use bookdb;
-- 向login表中插入数据
INSERT INTO login
VALUES
(1001, '张三', 'zspasswd', '2021-08-29 12:30:23', '2023-06-05 23:10:23'),
(1002, '李四', 'lspasswd', '2022-08-29 12:30:23', '2023-07-05 21:10:23'),
(1003, '王五', 'wwpasswd', '2023-04-29 12:30:23', '2023-06-14 23:23:23');
-- 向person表中插入数据
INSERT INTO person
VALUES
(1001, '张三', '三三', '', '/path/to/head1.jpg', '12345678901'),
(1002, '李四', '四四', '', '/path/to/head2.jpg', '12345678902'),
(1003, '王五', '五五', '', '/path/to/head3.jpg', '12345678903');
-- 显示login表中数据
SELECT
login_id AS '登录编号',
name AS '登录名',
passwd AS '密码',
create_time AS '注册时间',
last_time AS '最近登录时间'
FROM login;
-- 显示person表中数据
SELECT
login_id AS '登录编号',
real_name AS '真实姓名',
nick_name AS '昵称',
sex AS '性别',
head AS '头像路径',
phone AS '手机号'
FROM person;
+16
View File
@@ -0,0 +1,16 @@
/*
login表的passwd的字段名为auth_stringperson表名为profile_info
*/
-- 修改login表的passwd字段名为auth_string
ALTER TABLE login
CHANGE passwd auth_string VARCHAR(50);
-- 将person表重命名为profile_info
RENAME TABLE person TO profile_info;
-- 显示login表结构查看字段修改结果
DESCRIBE login;
-- 显示bookdb库结构查看表重命名结果
SHOW TABLES;
+68
View File
@@ -0,0 +1,68 @@
/*
2.
3. images
img_id, title, width, height
10
*/
-- 进入 bookdb 数据库
USE bookdb;
-- 创建个人图片集表 images
CREATE TABLE IF NOT EXISTS
images(
img_id INT PRIMARY KEY,
title VARCHAR(50),
width INT,
height INT,
user_id INT COMMENT '所属用户id',
FOREIGN KEY (user_id) REFERENCES login(login_id)
);
-- 为不同人员添加10条图片集记录
INSERT INTO images (img_id, title, width, height, user_id) VALUES
-- 1001 用户图集
(1, 'Image Set 1', 800, 600, 1001),
(2, 'Image Set 2', 1024, 768, 1001),
(3, 'Image Set 3', 1280, 720, 1001),
(4, 'Image Set 4', 800, 600, 1001),
(5, 'Image Set 5', 1024, 768, 1001),
(6, 'Image Set 6', 1280, 720, 1001),
(7, 'Image Set 7', 800, 600, 1001),
(8, 'Image Set 8', 1024, 768, 1001),
(9, 'Image Set 9', 1280, 720, 1001),
(10, 'Image Set 10', 800, 600, 1001),
-- 1002 用户图集
(11, 'Image Set 11', 800, 600, 1002),
(12, 'Image Set 12', 1024, 768, 1002),
(13, 'Image Set 13', 1280, 720, 1002),
(14, 'Image Set 14', 800, 600, 1002),
(15, 'Image Set 15', 1024, 768, 1002),
(16, 'Image Set 16', 1280, 720, 1002),
(17, 'Image Set 17', 800, 600, 1002),
(18, 'Image Set 18', 1024, 768, 1002),
(19, 'Image Set 19', 1280, 720, 1002),
(20, 'Image Set 20', 800, 600, 1002),
-- 1003 用户图集
(21, 'Image Set 21', 800, 600, 1003),
(22, 'Image Set 22', 1024, 768, 1003),
(23, 'Image Set 23', 1280, 720, 1003),
(24, 'Image Set 24', 800, 600, 1003),
(25, 'Image Set 25', 1024, 768, 1003),
(26, 'Image Set 26', 1280, 720, 1003),
(27, 'Image Set 27', 800, 600, 1003),
(28, 'Image Set 28', 1024, 768, 1003),
(29, 'Image Set 29', 1280, 720, 1003),
(30, 'Image Set 30', 800, 600, 1003);
-- 显示内容
DESCRIBE images;
SELECT
img_id AS '图片编号',
title AS '标题',
width AS '宽度',
height AS '高度',
user_id AS '所属用户id'
FROM images;
+22
View File
@@ -0,0 +1,22 @@
/*
NULL
*/
-- 进入 bookdb 数据库
USE bookdb;
-- 更新关联个人信息表数据为NULL
UPDATE profile_info SET login_id = NULL WHERE login_id = 1002;
-- 更新关联图片集表数据为NULL
UPDATE images SET user_id = NULL WHERE user_id = 1002;
-- 删除 login_id 为 1002 的用户
DELETE
FROM login
WHERE login_id = 1002;
-- 显示效果
SELECT * FROM login;
SELECT * FROM profile_info;
SELECT * FROM images;
+94
View File
@@ -0,0 +1,94 @@
/*
stu.sql脚本中的数据表完成下列操作
1
2
3
4
5 33
6
770~80
stu.sql文件 stu.sql文件后 studb2, source
student
teacher
course
sc
floor(datediff(now(), age)/365) as age
*/
-- 删除已存在同名数据库 studb2
drop database if exists studb2;
-- 新建数据库 studb2
create database studb2;
-- 进入数据库 studb2
use studb2;
-- 导入 stu.sql 数据到数据库 stu
source stu.sql;
-- 显示导入结果
show tables;
-- 查询学生选课表中的全部数据
SELECT *
FROM course;
-- 查询全体学生的姓名、学号和所在系
SELECT
student.name AS '姓名',
student.sid AS '学号',
xb.name AS '所在系'
FROM student
JOIN xb
ON student.xid = xb.xid;
-- 查询全体学生的姓名及其出生年份
SELECT
name AS '学生姓名',
YEAR(age) AS '出生年份'
FROM student;
-- 查询计算机系全体学生的姓名
SELECT
xb.name AS '所在系',
student.name AS '姓名'
FROM xb
JOIN student
ON xb.xid = student.xid
WHERE xb.name = '计算机系';
-- 查询年龄在33岁以下的学生的姓名及年龄
SELECT
name AS '姓名',
FLOOR(DATEDIFF(NOW(), age)/365) AS '年龄'
FROM student
WHERE FLOOR(DATEDIFF(NOW(), age)/365) < 33;
-- 查询考试成绩有不及格的学生的学号 DISTINCT 用于结果行去重
SELECT DISTINCT
student.sid AS '学号'
FROM student
JOIN sc
ON student.sid = sc.sid
WHERE sc.score < 60;
-- 查询成绩在70-80分之间的学生,包括学号,课程号和成绩
SELECT
student.sid AS '学号',
sc.cid AS '课程号',
sc.score AS '成绩'
FROM student
JOIN sc
ON student.sid = sc.sid
-- WHERE sc.score BETWEEN 70 AND 80;
WHERE sc.score >= 70 and sc.score <= 80;
+217
View File
@@ -0,0 +1,217 @@
-- MySQL dump 10.13 Distrib 5.6.25, for Win64 (x86_64)
--
-- Host: localhost Database: stu
-- ------------------------------------------------------
-- Server version 5.6.25-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `a`
--
DROP TABLE IF EXISTS `a`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `a` (
`year` int(11) DEFAULT NULL,
`month` int(11) DEFAULT NULL,
`amount` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `a`
--
LOCK TABLES `a` WRITE;
/*!40000 ALTER TABLE `a` DISABLE KEYS */;
INSERT INTO `a` VALUES (1991,1,1.1),(1991,2,1.2),(1992,1,2.1),(1992,2,2.2);
/*!40000 ALTER TABLE `a` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `course`
--
DROP TABLE IF EXISTS `course`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `course` (
`cid` varchar(10) DEFAULT NULL,
`name` varchar(10) DEFAULT NULL,
`tid` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `course`
--
LOCK TABLES `course` WRITE;
/*!40000 ALTER TABLE `course` DISABLE KEYS */;
INSERT INTO `course` VALUES ('01','语文','02'),('02','数学','01'),('03','英语','03');
/*!40000 ALTER TABLE `course` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `sc`
--
DROP TABLE IF EXISTS `sc`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sc` (
`sid` varchar(10) DEFAULT NULL,
`cid` varchar(10) DEFAULT NULL,
`score` decimal(18,1) DEFAULT NULL,
KEY `sid_cid_index` (`sid`,`cid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `sc`
--
LOCK TABLES `sc` WRITE;
/*!40000 ALTER TABLE `sc` DISABLE KEYS */;
INSERT INTO `sc` VALUES ('01','01',80.0),('01','02',90.0),('01','03',99.0),('02','01',70.0),('02','02',60.0),('02','03',80.0),('03','01',80.0),('03','02',80.0),('03','03',80.0),('04','01',50.0),('04','02',30.0),('04','03',20.0),('05','01',76.0),('05','02',87.0),('06','01',31.0),('06','03',34.0),('07','02',89.0),('07','03',98.0);
/*!40000 ALTER TABLE `sc` ENABLE KEYS */;
UNLOCK TABLES;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = utf8 */ ;
/*!50003 SET character_set_results = utf8 */ ;
/*!50003 SET collation_connection = utf8_general_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger watch_sc_delete before delete on sc for each row
insert into sc_copy values (OLD.sid, OLD.cid, OLD.score) */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
--
-- Table structure for table `student`
--
DROP TABLE IF EXISTS `student`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `student` (
`sid` varchar(10) DEFAULT NULL,
`name` varchar(10) DEFAULT NULL,
`age` datetime DEFAULT NULL,
`sex` varchar(10) DEFAULT NULL,
`xid` varchar(10) DEFAULT NULL,
UNIQUE KEY `name_unique` (`name`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `student`
--
LOCK TABLES `student` WRITE;
/*!40000 ALTER TABLE `student` DISABLE KEYS */;
INSERT INTO `student` VALUES ('01','赵雷','1990-01-01 00:00:00','','01'),('02','钱电','1990-12-21 00:00:00','','01'),('03','孙风','1990-05-20 00:00:00','','02'),('04','李云','1990-08-06 00:00:00','','01'),('05','周梅','1991-12-01 00:00:00','','03'),('06','吴兰','1992-03-01 00:00:00','','02'),('07','郑竹','1989-07-01 00:00:00','','03'),('08','王菊','1990-01-20 00:00:00','','04'),('110','disen','1991-10-10 00:00:00','','01');
/*!40000 ALTER TABLE `student` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `teacher`
--
DROP TABLE IF EXISTS `teacher`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `teacher` (
`tid` varchar(10) DEFAULT NULL,
`name` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `teacher`
--
LOCK TABLES `teacher` WRITE;
/*!40000 ALTER TABLE `teacher` DISABLE KEYS */;
INSERT INTO `teacher` VALUES ('01','张三'),('02','李四'),('03','王五');
/*!40000 ALTER TABLE `teacher` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `update_pwd_log`
--
DROP TABLE IF EXISTS `update_pwd_log`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `update_pwd_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`username` varchar(20) DEFAULT NULL,
`old_pwd` varchar(50) DEFAULT NULL,
`new_pwd` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `update_pwd_log`
--
LOCK TABLES `update_pwd_log` WRITE;
/*!40000 ALTER TABLE `update_pwd_log` DISABLE KEYS */;
INSERT INTO `update_pwd_log` VALUES (1,'2022-03-29 06:31:49','disen','123','666');
/*!40000 ALTER TABLE `update_pwd_log` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `xb`
--
DROP TABLE IF EXISTS `xb`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `xb` (
`xid` varchar(10) NOT NULL,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `xb`
--
LOCK TABLES `xb` WRITE;
/*!40000 ALTER TABLE `xb` DISABLE KEYS */;
INSERT INTO `xb` VALUES ('01','计算机系'),('02','信息系'),('03','英语系'),('04','数学系');
/*!40000 ALTER TABLE `xb` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2022-04-28 18:44:23
+10
View File
@@ -0,0 +1,10 @@
use studb;
insert into t_emp values
(1,'jack','17189792205',12000,'2021-10-12'),
(2,'lucy','17178982206',2200,'2022-11-15'),
(3,'disen','17178979385',22000,'2022-10-12'),
(4,'mack','17178982209',5000,'2023-08-15'),
(5,'judy','17178982105',9000,'2023-08-20');
select * from t_emp;
+12
View File
@@ -0,0 +1,12 @@
-- 单条数据插入
insert into t_stu values(1,'张三','','1991-01-15');
-- 按照指定格式插入
insert into t_stu(sid,name,birthday,sex)
values(2,'王龙','1990-12-18','');
-- 元组插入
insert into t_stu values
(3,'刘冬冬','','1992-08-21'),
(4,'刘红','','1992-05-19'),
(5,'王玉玉','','1991-08-12');
+3
View File
@@ -0,0 +1,3 @@
use studb;
select * from t_emp where salary>5000;
+5
View File
@@ -0,0 +1,5 @@
-- 查询测试
-- select * from t_stu where name like '刘';
select * from t_stu where name like '刘%';
select * from t_stu where birthday like '1991%';
+10
View File
@@ -0,0 +1,10 @@
use studb;
update t_emp
set salary = salary + 1000;
update t_emp
set salary = salary * 1.15
where tel like '%8979$';
select * from t_emp;
+20
View File
@@ -0,0 +1,20 @@
-- 修改测试
update t_stu
set sex='',birthday='1998-02-15'
where name = '刘红';
update t_stu
set sex='',birthday='1990-12-28'
where sid = 1;
update t_stu
-- set birthday=CURDATE()
set birthday=null
where sid = 5;
/*
update t_stu
-- 使用函数加 5 天
set birthday = DATE_ADD(birthday,INTERVAL 5 DAY)
where sid = 2;
*/