Compare commits
14 Commits
e6757b9935
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b818d11bd | |||
| e11f684219 | |||
| b520c1de82 | |||
| db9e1dd070 | |||
| 8b63cc049a | |||
| 8e8af08fcf | |||
| ffc2656985 | |||
| 721846a61d | |||
| 663a501a63 | |||
| 0df47fc15c | |||
| 7d8e55d275 | |||
| d1bc1e2410 | |||
| 8df60e2dc6 | |||
| 49d2f0cabb |
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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&tpl=mn&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>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a> 京ICP证030173号 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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()则不能正常返回数据。因此,在清理函数内,将当前堆的数据赋值给全局变量,在主线程中进行使用。
|
||||
*/
|
||||
@@ -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, ¶m);
|
||||
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, ¶m);
|
||||
struct sched_param param2;
|
||||
param2.__sched_priority = 12;
|
||||
pthread_setschedparam(tid2, SCHED_FIFO, ¶m2);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
use studb;
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
use studb;
|
||||
|
||||
-- 所有列的查询
|
||||
select * from t_stu;
|
||||
@@ -0,0 +1,6 @@
|
||||
use studb;
|
||||
|
||||
-- 查询2022年入职的所有员工
|
||||
select *
|
||||
from t_emp
|
||||
where hire_date between '2022-01-01' and '2022-12-31';
|
||||
@@ -0,0 +1,7 @@
|
||||
use studb;
|
||||
|
||||
-- 按学生的出生日期降序显示
|
||||
select *
|
||||
from t_stu
|
||||
order by birthday desc;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
use studb;
|
||||
|
||||
-- 显示年龄最大的前两位学生
|
||||
-- 出去 NULL
|
||||
select *
|
||||
from t_stu
|
||||
where birthday is not null
|
||||
-- 年龄越大,出生日期越前
|
||||
order by birthday asc
|
||||
limit 0,2;
|
||||
@@ -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;
|
||||
@@ -0,0 +1,4 @@
|
||||
use studb;
|
||||
|
||||
-- 查询指定的列
|
||||
select sid, name from t_stu;
|
||||
@@ -0,0 +1,5 @@
|
||||
use studb;
|
||||
|
||||
-- 查询到的内容按指定的标题显示
|
||||
select sid '学号', name as '姓名'
|
||||
from t_stu;
|
||||
@@ -0,0 +1,4 @@
|
||||
use studb;
|
||||
|
||||
select t_stu.sid,t_stu.sex
|
||||
from t_stu;
|
||||
@@ -0,0 +1,5 @@
|
||||
use studb;
|
||||
|
||||
-- 使用表的别名查询
|
||||
select a.*
|
||||
from t_stu a;
|
||||
@@ -0,0 +1,5 @@
|
||||
use studb;
|
||||
|
||||
-- 查询字段是一个表达式
|
||||
select sid, name, 100 as score
|
||||
from t_stu;
|
||||
@@ -0,0 +1,10 @@
|
||||
use studb;
|
||||
|
||||
-- 从多个表中查询数据时,如果存在相同的字段时,字段名前必须加表名
|
||||
select *
|
||||
from t_stu t1, t_stu t2;
|
||||
where t1.sid > 2 and t2.sid > 3;
|
||||
|
||||
/*
|
||||
本案例打印结果会出现笛卡尔乘积
|
||||
*/
|
||||
@@ -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案例的改写,去重
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
use studb;
|
||||
|
||||
-- 查询员工表中手机号第7位是8的员工
|
||||
select *
|
||||
from t_emp
|
||||
where tel like '______8%';
|
||||
@@ -0,0 +1,6 @@
|
||||
use studb;
|
||||
|
||||
-- 查询disen和jack两位员工
|
||||
select *
|
||||
from t_emp
|
||||
where name in ('disen', 'jack');
|
||||
+171
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
-- comment 表示字段的说明 (备份)
|
||||
create table t_course(
|
||||
cid int,
|
||||
name varchar(50) comment '课程名',
|
||||
tid int comment '教师编号'
|
||||
);
|
||||
@@ -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
|
||||
);
|
||||
@@ -0,0 +1,5 @@
|
||||
create table t_score(
|
||||
sid int,
|
||||
cid int,
|
||||
score decimal(5,2)
|
||||
);
|
||||
@@ -0,0 +1,7 @@
|
||||
-- sql comment
|
||||
create table t_student(
|
||||
sid int,
|
||||
name varchar(20),
|
||||
sex varchar(2),
|
||||
birthday date
|
||||
);
|
||||
@@ -0,0 +1,4 @@
|
||||
create table t_teacher(
|
||||
tid integer,
|
||||
name varchar(50)
|
||||
);
|
||||
@@ -0,0 +1,4 @@
|
||||
use studb;
|
||||
|
||||
delete from t_emp where hire_date > '2022-12-31';
|
||||
select * from t_emp;
|
||||
@@ -0,0 +1,8 @@
|
||||
-- 删除测试
|
||||
use studb;
|
||||
|
||||
create table if not exists t_stu3
|
||||
select * from t_stu;
|
||||
|
||||
delete from t_stu3
|
||||
where sex='男';
|
||||
@@ -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
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
创建数据库bookdb,在bookdb数据库中创建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;
|
||||
@@ -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;
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
分别向login、person表中插入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;
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
修改login表的passwd的字段名为auth_string,修改person表名为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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
根据stu.sql脚本中的数据表完成下列操作:
|
||||
|
||||
1) 查询学生选课表中的全部数据
|
||||
|
||||
2) 查询全体学生的姓名、学号和所在系。
|
||||
|
||||
3) 查询全体学生的姓名及其出生年份。
|
||||
|
||||
4) 查询计算机系全体学生的姓名。
|
||||
|
||||
5) 查询年龄在33岁以下的学生的姓名及年龄。
|
||||
|
||||
6)查询考试成绩有不及格的学生的学号
|
||||
|
||||
7)查询成绩在70~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;
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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');
|
||||
@@ -0,0 +1,3 @@
|
||||
use studb;
|
||||
|
||||
select * from t_emp where salary>5000;
|
||||
@@ -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%';
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
*/
|
||||
Reference in New Issue
Block a user