In Ubuntu, Why the sequence is changed? - multithreading

I compile this code in Ubuntu. I did it more than 10 times but I got only AAA BBB CCC . I believe sequence can be changed but I don't know why. Please somebody kindly tell me the reason.
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
void *thread_entry(void *ptr)
{
char *name = (char *)ptr;
printf("%s-A\n", name);
sleep(1); //sched_yield();
printf("%s-B\n", name);
sleep(1); //sched_yield();
printf("%s-C\n", name);
}
int main()
{
#define MAX_THREAD 3
pthread_t thread[MAX_THREAD];
char *thread_name[MAX_THREAD] = {"thread1", "thread2", "thread3"};
int i;
for (i = 0; i < MAX_THREAD; i++)
pthread_create(&thread[i], NULL, thread_entry, thread_name[i]);
for (i = 0; i < MAX_THREAD; i++)
pthread_join(thread[i], NULL);
return 0;
}

Theoretically it's possible, but it's very unlikely you would see another ordering.
You spawn 3 threads, then one of them prints "A" and waits for 1 second until it will print "B". One second of sleeping is far more than enough for the rest threads to print "A". Same for "B" and "C".

Related

I'm trying to create a string with n characters by allocating memories with malloc, but I have a problem

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n;
printf("Length? ");
scanf("%d", &n);
getchar();
char* str = (char*)malloc(sizeof(char) * (n+1));
fgets(str,sizeof(str),stdin);
for (int i = 0; i < n; i++)
printf("%c\n", str[i]);
free(str);
}
Process results like this!
Length? 5
abcde
a
b
c
?
(I wanted to upload the result image, but I got rejected since I didn't have 10 reputations)
I can't figure out why 'd' and 'e' won't be showing in the results.
What is the problem with my code??
(wellcome to stackoverflow :) (update #1)
str is a pointer to char instead of a character array therefore sizeof(str) is always 8 on 64-bit or 4 on 32-bit machines, no matter how much space you have allocated.
Demo (compilation succeeds only if X in static_assert(X) holds):
#include <assert.h>
#include <stdlib.h>
int main(void){
// Pointer to char
char *str=(char*)malloc(1024);
#if defined _WIN64 || defined __x86_64__ || defined _____LP64_____
static_assert(sizeof(str)==8);
#else
static_assert(sizeof(str)==4);
#endif
free(str);
// Character array
char arr[1024];
static_assert(sizeof(arr)==1024);
return 0;
}
fgets(char *str, int num, FILE *stream) reads until (num-1) characters have been read
Instead of fgets(str,sizeof(str),stdin) please fgets(str,n+1,stdin)
Fixed version:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
int n=0;
printf("Length? ");
scanf("%d",&n);
getchar();
char *str=(char*)calloc((n+1),sizeof(char));
static_assert(
sizeof(str)==sizeof(char*) && (
sizeof(str)==4 || // 32-bit machine
sizeof(str)==8 // 64-bit machine
)
);
fgets(str,n+1,stdin);
for(int i=0;i<n;++i)
printf("%c\n",str[i]);
free(str);
str=NULL;
}
Length? 5
abcde
a
b
c
d
e

How to get an array of strings without using argv - CS50 pset2

I'm currently doing the CS50 Harvard Course and I'm stuck in problem set 2.
I made this program that takes a name and prints the initials, it takes the name in the command line. How can I use get_string() instead of argv, and argc wich is very unorthodox and sloppy, so I can prompt the user to give me her/his name. Thank you.
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(int argc, string argv[])
{
//How do I use Get_string() so I don't have to use argv and argc??
//iterate over strings on the vector (words)
for (int i = 0; i < argc; i++)
{
//prints the 0 character of each string, use "toupper" to convert into capital letters
printf("%c", toupper(argv[i][0]));
}
printf("\n");
}
use Array,
let's say for 10 names
string name[10];
for (int i = 0; i < 10; i++)
{
name[i] = get_string("Enter your name: /n");
}

Simple Cypher Program Not Working (CS50)

On week 2 of CS50 and I've hit a wall. My code is supposed to prompt a user for plaintext and then print a simple cypher on the next line. Problem is, my code keeps printing the exact input for the user rather than scrambling. My code is below.
Note: the error in my code is likely down in the for loop, inside the respective printf functions.
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main (int argc, string argv[]){
if (argc != 2){
printf("You must enter two arguments, the second being a single digit integer!\n");
return 1;
}
int key = atoi(argv[1]);
printf("What do you want to encrpyt?");
string s = get_string();
for(int i=0; i < strlen(s); i++){
if (isupper(s[i])==true){
printf("%c",((s[i] + key)));
}
if (islower(s[i])==true){
printf("%c",s[i] + key);
}
else {
printf("%c",s[i]);
}
}
}
Fixed it. The if statement syntax was wrong, so the program was skipping over the cypher text. I need to delete the "==true" out of the if statement.

Why thread_id creates not in order?

I tried to create 10 threads, and output each tread index. My code is shown as below, I am wondering why they are repeating instead of arranging in order?
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "util.h"
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
pthread_mutex_t request_buf_lock = PTHREAD_MUTEX_INITIALIZER;
void * worker(void *arg)
{
int thread_id = *(int*)arg;
// int requests_handled = 0;
//requests_handled = requests_handled + 1;
printf("%d\n",thread_id);
}
int main(int argc, char** argv)
{
pthread_t dispatchers[100];
pthread_t workers[100];
int i;
int * thread_id = malloc(sizeof(int));
for (i = 0; i < 10; i++) {
*thread_id = i;
pthread_create(&workers[i], NULL, worker, (void*)thread_id);
}
for (i = 0; i < 10; i++) {
pthread_join(workers[i], NULL);
}
return 0;
}
And the output result is:
4
5
5
6
6
6
7
8
9
9
But I expected it as:
0
1
2
3
4
5
6
7
8
9
Anyone has any idea or advice?
All 10 threads execute in parallel, and they all share a single int object, the one created by the call to malloc.
By the time your first thread executes its printf call, the value of *thread_id has been set to 4. Your second and third threads execute their printf calls when *thread_id has been set to 5. And so on.
If you allocate a separate int object for each thread (either by moving the malloc call inside the loop or just by declaring an array of ints), you'll get a unique thread id in each thread. But they're still likely to be printed in arbitrary order, since there's no synchronization among the threads.

Why "ls" is not colored after forkpty()

Why output of ls executed here is not colored?
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pty.h>
#include <sys/wait.h>
int main(int argc, char **argv ) {
termios termp; winsize winp;
int amaster; char name[128];
if (forkpty(&amaster, name, &termp, &winp) == 0) {
system("ls"); // "ls --color" will work here!
return 0;
}
wait(0);
char buf[128]; int size;
while (1) {
size = read(amaster, buf, 127);
if (size <= 0) break;
buf[size] = 0;
printf("%s", buf);
}
return 0;
}
According to man (and ls.c that I am inspecting) it should be colored if isatty() returns true. After forkpty() it must be true. Besides, ls DOES output in columnized mode in this example! Which means it feels it has tty as output.
Of course I do not want only ls to output color, but an arbitrary program to feel that it has real color enabled tty behind.
I just wrote a simple test:
#include <unistd.h>
int main() {
printf("%i%i%i%i%i\n", isatty(0), isatty(1), isatty(2), isatty(3), isatty(4));
}
and call it in a child part of forkpty, and it displays 11100, which means ls should be colored!
OK, as it seems the fact that ls produces no color output has nothing to do with forkpty(). It is just not color enabled by default. But now, maybe that's another question, why it is not color if it just checks isatty()?

Resources