c: thread in Ubuntu 22.04

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/**
 * @file helloworld.c
 * @author your name (geovindu@163.com)
 * @brief thread
 * @version 0.1
 * @date 2023-10-24
 * ide: vscode  c11,c17  Ubuntu 22.04
 * @copyright Copyright (c) 2023 站在巨人的肩膀上 Standing on the Shoulders of Giants 2023
 *
 */
 
#include<stdlib.h>
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<malloc.h>
#include<time.h>
#include<unistd.h>
#include<sys/wait.h>
#include<threads.h>
#include<math.h>
#include<unistd.h>  //Header file for sleep(). man 3 sleep for details.
#include<pthread.h>
 
#include "include/CheckTieck.h"
#include "include/TakeNumber.h"
 
#define threadcout 5
 
//
//
thrd_t threadId[threadcout];
 
 
mtx_t task_mtx;  
 
struct timespec duration={.tv_sec=1,.tv_nsec=0};
 
size_t task=0;
 
 
/**
 * @brief 线程
 *
 * @param agr
 * @return int
 */
 int execrteTask(void *agr)
 {
 
    mtx_lock(&task_mtx);
    size_t local_task = ++task;
    mtx_unlock(&task_mtx);
 
    //  mtx_lock(&task_mtx);                          // mutex lock - blocks until acquired
    //  printf_s("Task %zd started.\n", ++task);
    printf("Task %zd started.\n", local_task);
 
    thrd_sleep(&duration, NULL);                    // Just to make things take longer...
    double x = 0;
    for(int i = 0 ; i< 1000000000 ; ++i)
        x = sqrt(3.1415926);
 
    printf("  Task %zd finished\n", local_task);
    //  printf_s("  Task %zd finished\n", task);
    //  mtx_unlock(&task_mtx);                         // mutex unlock - for use by other threads
    return 0;
 }
 
// 定义一个结构体,用于存储函数的参数和返回值
typedef struct {
    int x; // 输入参数
    int y; // 返回值
} data_t;
 
// 定义一个函数,接受一个指向data_t结构体的指针,打印该结构体中的x值的平方,并将该值加一存入y中
void *square_and_add_one(void *arg) {
    data_t *data = (data_t *)arg;
    printf("The square of %d is %d\n", data->x, data->x * data->x);
    data->y = data->x + 1;
    return NULL;
}
 
/**
 * @brief
 *
 * @param argc
 * @param argv
 * @return int
 */
int main(void)
{
    int argc;
    char *argv;//[]={'\0'};
    char ddd[11]="The hello world";
    argv=ddd;
    argc=2;
 
    // 检查命令行参数的个数,至少需要一个参数
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <number>\n", argv[0]);
        exit(1);
    }
 
    // 将第一个参数转换为整数
    printf("%s",&argv[1]);
    int thdnum = atoi(&argv[1]);
 
    // 创建一个data_t结构体,并初始化其x值为num
    data_t data;
    data.x = thdnum;
 
    // 创建一个线程,并传入square_and_add_one函数和data结构体的地址
    pthread_t tid;
    pthread_create(&tid, NULL, square_and_add_one, &data);
 
    // 等待线程结束,并打印其返回值
    pthread_join(tid, NULL);
    printf("The thread returned %d\n", data.y);
 
 
 
 
        if(thrd_error == mtx_init(&task_mtx, mtx_timed))
        {
            //int ret = vfprintf(stdout, fmt, vl);
            fprintf(stderr, "Mutex creation failed.\n");  //stderr
            thrd_exit(-2);
        }
 
    // Create the threads to carry out the tasks concurrently
    for(size_t i = 0 ; i<threadcout ; ++i)
        if(thrd_error == thrd_create(&(threadId[i]), execrteTask, NULL))
        {
            fprintf(stderr, "Thread creation failed.\n");
            thrd_exit(-1);
        }
 
    // Join the additional threads to the main thread
    for(size_t j = 0 ; j <threadcout ; ++j)
        thrd_join(threadId[j], NULL);
 
    pid_t pid;
    int status;
 
    pid = fork();  // 创建一个新进程
 
    if (pid < 0) {  // 如果创建失败,输出错误信息
        fprintf(stderr, "Fork Failed");
        return 1;
    } else if (pid == 0) {  // 子进程
        printf("I am the child %d\n",pid);
        execl("/bin/ls", "ls", NULL);  // 在子进程中执行 /bin/ls 程序
        printf("I am the child %d, and execl failed\n",pid);  // 如果 execl 返回,那么说明出错
    } else // 父进程
        wait(&status);  // 等待子进程结束
        printf("I am the parent %d, and my child has ended\n",pid);
    }
 
 
    printf("hello wolrd, c launguage! weblcome geovindu!涂聚文");
  
    QueueCalling *queue1;
       
    char select='1';
    //int num=1;//顾客序号
    int num=0; //叫号编号
    queue1=QueueInit(); //初始化队列
    if(queue1==NULL)
    {
        printf("创建队列时出错!\n");
        //getch();
        getchar();
        return 0;
    }
    do{
        //这里处理,列表不会显示两次
        if(select=='1' || select=='2')
        {
            printf("\n请选择具体操作:\n");
            printf("1.新到顾客\n");
            printf("2.下一个顾客\n");
            printf("0.退出\n") ;
            fflush(stdin);
        }
  
        select=getchar();//getch();
        switch(select)
        {
            case '1':
                add(queue1);
                printf("\n现在共有%d位顾客在等候!\n",QueueLen(queue1));
                break;
            case '2':
                next(queue1);
                printf("\n现在共有%d位顾客在等候!\n",QueueLen(queue1));
                break;
            case '0':
                break;
        }     
    }while(select!='0');
    QueueFree(queue1); //释放队列
    //getch();
    getchar();
     
    return 0;
}

  

输出:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
 * @file helloworld.c
 * @author your name (geovindu@163.com)
 * @brief thread
 * @version 0.1
 * @date 2023-10-24
 * ide: vscode  c11,c17  Ubuntu 22.04
 * @copyright Copyright (c) 2023 站在巨人的肩膀上 Standing on the Shoulders of Giants 2023
 *
 */
 
#include<stdlib.h>
#include<stdio.h>
#include<ctype.h>
#include<sys/types.h>
#include<string.h>
#include<malloc.h>
#include<time.h>
#include<unistd.h>
#include<sys/wait.h>
#include<threads.h>
#include<math.h>
#include<unistd.h>  //Header file for sleep(). man 3 sleep for details.
#include<pthread.h>
 
#include "include/CheckTieck.h"
#include "include/TakeNumber.h"
#include "include/twoDimensional.h"
 
#define threadcout 5
 
//
//
thrd_t threadId[threadcout];
 
 
mtx_t task_mtx;  
 
struct timespec duration={.tv_sec=1,.tv_nsec=0};
 
size_t task=0;
 
 
/**
 * @brief 线程
 *
 * @param agr
 * @return int
 */
 int execrteTask(void *agr)
 {
 
    mtx_lock(&task_mtx);
    size_t local_task = ++task;
    mtx_unlock(&task_mtx);
 
    //  mtx_lock(&task_mtx);                          // mutex lock - blocks until acquired
    //  printf_s("Task %zd started.\n", ++task);
    printf("Task %zd started.\n", local_task);
 
    thrd_sleep(&duration, NULL);                    // Just to make things take longer...
    double x = 0;
    for(int i = 0 ; i< 1000000000 ; ++i)
        x = sqrt(3.1415926);
 
    printf("  Task %zd finished\n", local_task);
    //  printf_s("  Task %zd finished\n", task);
    //  mtx_unlock(&task_mtx);                         // mutex unlock - for use by other threads
    return 0;
 }
 
// 定义一个结构体,用于存储函数的参数和返回值
typedef struct {
    int x; // 输入参数
    int y; // 返回值
} data_t;
 
// 定义一个函数,接受一个指向data_t结构体的指针,打印该结构体中的x值的平方,并将该值加一存入y中
void *square_and_add_one(void *arg) {
    data_t *data = (data_t *)arg;
    printf("The square of %d is %d\n", data->x, data->x * data->x);
    data->y = data->x + 1;
    return NULL;
}
 
/**
 * @brief
 *
 * @param argc
 * @param argv
 * @return int
 */
int main(void)
{
 
    pid_t pid;
    int status;
 
    pid = fork();  // 创建一个新进程
 
    if (pid < 0) {  // 如果创建失败,输出错误信息
        fprintf(stderr, "Fork Failed");
        return 1;
    } else if (pid == 0) {  // 子进程
        printf("I am the child %d\n",pid);
        //execl("/bin/ls", "ls", NULL);  // 在子进程中执行 /bin/ls 程序
 
        //execl("/usr/bin/env", "env", NULL, NULL); //OK打印环境变量
        //execl("/bin/sh", "sh", "-c","echo 'Hello!' >> test.txt",(char *) NULL); //OK 添加到文件文尾
        execl("/bin/sh", "sh", "-c","echo 'Hello!' > test.txt",(char *) NULL); //OK 只有hello的字符
        //execle("/bin/ls","ls","./",NULL); //   ok显示文件夹的文件
        //execl("/bin/sh", "sh", "-c", "/bin/cat > test.txt", (char *) NULL); //ok 创建文件,并可以输入内容,关闭即保存
        //execl("/bin/cat","cat","1.txt","2.txt",NULL);//显示了两个文件内容
        //execl("/bin/cat", "cat", "-n", "1.js", NULL);//ok 读文件显示号
        //execl("/bin/cat", "cat", "-n", "1.txt", NULL); //ok 读文件显示号
        printf("I am the child %d, and execl failed\n",pid);  // 如果 execl 返回,那么说明出错
    } else // 父进程
        wait(&status);  // 等待子进程结束
        printf("I am the parent %d, and my child has ended\n",pid);
    }
 
   return 0;
}

 

 

 

如何在程序里使用这些内存。

C的存储结构是非常重要的,C的存储结构主要由堆区、栈区、全局常量区、程序代码区组成。其中重要的是堆和栈,它们都属于RAM; 因此,它们是个稳定的,并且在运行时经常会改变。

函数的局部变量是在栈中创建的;同时,在堆中指针是需要你的程序手动处理的(malloc/free),堆的作用域是在程序被运行时。

栈存储变量的空间比堆的小,其原理是为了让栈存储那些只需要短暂的变量。

另一方面,堆可以处理内存需求更大的变量,堆是动态分配的。当然,堆的访问速度取决于每个段的访问对象。堆由开发人员手动处理。也就是说,有可能出现内存泄漏。堆中的变量是全局的,可以通过指针访问。

栈是一个后进先出(last-in-first-out,LIFO)的结构,这对于递归函数非常有用。每次声明一个变量,它将被在于该段的顶部(这就是一个使用pust-pop函数的后进先出结构的栈)。

 

 

输入输出格式说明符:

输出格式说明符

printf

printf_s

sprintf

sprintf_s

snprintf

snprintf_s

fprintf

fprintf_s

vfprintf

vsprintf

vprintf

vsnprintf

vfprintf_s

vprintf_s

vsnprintf_s

vsprintf_s

输入格式说明符

scanf

scanf_s

vscanf

vscanf_s

sscanf

sscanf_s

vsscanf

vsscanf_s

fscanf

fscanf_s

vfscanf

vfscanf_s

 来源: Beginnin C: From Beginner to Pro, Sixth Edition 

https://github.com/Apress/beginning-c-6e

 

https://www.demo2s.com/c/c-execl-bin-ls-ls-a-l-null.html

#include <unistd.h>

extern char **environ;
int execl(const char *path, const char *arg0, ... /*, (char *)0 */);
int execle(const char *path, const char *arg0, ... /*,
(char *)0, char *const envp[]*/);
int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);
int execv(const char *path, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
int fexecve(int fd, char *const argv[], char *const envp[]);

1
execl("/bin/cat","cat","1.js",">","2.js",NULL);

  

posted @   ®Geovin Du Dream Park™  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2022-10-24 Python: Observer Pattern
2022-10-24 Python: Mediator Pattern
2011-10-24 Csharp windowform bindingNavigator,bindingSource,DataGridView簡單分頁:首頁,上一頁,下一頁,末頁
2009-10-24 World Currency Symbols世界货币符号
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示